Browse Source

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

Raanan Weber 7 years ago
parent
commit
7922db7567
100 changed files with 32923 additions and 49095 deletions
  1. 1 0
      .gitignore
  2. 11705 10459
      Playground/babylon.d.txt
  3. 4 4
      Playground/debug.html
  4. 4 4
      Playground/index-local.html
  5. 4 4
      Playground/index.html
  6. 4 4
      Playground/indexStable.html
  7. 4 2
      Playground/js/index.js
  8. BIN
      Playground/textures/colorGrade-highContrast.png
  9. BIN
      Playground/textures/colorGrade-inverted.png
  10. BIN
      Playground/textures/colorGrade-posterize.png
  11. BIN
      Playground/textures/down.png
  12. BIN
      Playground/textures/up.png
  13. 28 7
      Tools/Gulp/config.json
  14. 11 1
      Tools/Gulp/gulp-validateTypedoc.js
  15. 4 2
      Tools/Gulp/gulpfile.js
  16. 13237 13032
      dist/preview release/babylon.d.ts
  17. 50 49
      dist/preview release/babylon.js
  18. 476 71
      dist/preview release/babylon.max.js
  19. 476 71
      dist/preview release/babylon.no-module.max.js
  20. 50 49
      dist/preview release/babylon.worker.js
  21. 478 73
      dist/preview release/es6.js
  22. 1 1
      dist/preview release/gltf2Interface/package.json
  23. 1012 27
      dist/preview release/gui/babylon.gui.d.ts
  24. 1201 57
      dist/preview release/gui/babylon.gui.js
  25. 5 4
      dist/preview release/gui/babylon.gui.min.js
  26. 1012 27
      dist/preview release/gui/babylon.gui.module.d.ts
  27. 1 1
      dist/preview release/gui/package.json
  28. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  29. 34 30
      dist/preview release/inspector/babylon.inspector.css
  30. 1 0
      dist/preview release/inspector/babylon.inspector.d.ts
  31. 64 53
      dist/preview release/inspector/babylon.inspector.js
  32. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  33. 1 1
      dist/preview release/inspector/package.json
  34. 4 2
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  35. 3 3
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  36. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  37. 87 38
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  38. 165 107
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  39. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  40. 87 38
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  41. 168 108
      dist/preview release/loaders/babylon.glTFFileLoader.js
  42. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  43. 87 38
      dist/preview release/loaders/babylonjs.loaders.d.ts
  44. 168 108
      dist/preview release/loaders/babylonjs.loaders.js
  45. 4 4
      dist/preview release/loaders/babylonjs.loaders.min.js
  46. 87 38
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  47. 2 2
      dist/preview release/loaders/package.json
  48. 1 1
      dist/preview release/materialsLibrary/babylon.mixMaterial.js
  49. 1 1
      dist/preview release/materialsLibrary/babylon.mixMaterial.min.js
  50. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js
  51. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  52. 1 1
      dist/preview release/materialsLibrary/package.json
  53. 1 1
      dist/preview release/postProcessesLibrary/package.json
  54. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  55. 14 5
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  56. 64 47
      dist/preview release/serializers/babylon.glTF2Serializer.js
  57. 2 2
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  58. 14 5
      dist/preview release/serializers/babylonjs.serializers.d.ts
  59. 64 47
      dist/preview release/serializers/babylonjs.serializers.js
  60. 2 2
      dist/preview release/serializers/babylonjs.serializers.min.js
  61. 14 5
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  62. 2 2
      dist/preview release/serializers/package.json
  63. 1 24135
      dist/preview release/typedocValidationBaseline.json
  64. 47 46
      dist/preview release/viewer/babylon.viewer.js
  65. 644 179
      dist/preview release/viewer/babylon.viewer.max.js
  66. 1 1
      dist/preview release/viewer/package.json
  67. 11 2
      dist/preview release/what's new.md
  68. 134 10
      gui/src/2D/advancedDynamicTexture.ts
  69. 50 0
      gui/src/2D/controls/button.ts
  70. 17 0
      gui/src/2D/controls/checkbox.ts
  71. 13 0
      gui/src/2D/controls/colorpicker.ts
  72. 58 1
      gui/src/2D/controls/container.ts
  73. 253 8
      gui/src/2D/controls/control.ts
  74. 6 0
      gui/src/2D/controls/ellipse.ts
  75. 49 1
      gui/src/2D/controls/image.ts
  76. 28 0
      gui/src/2D/controls/inputText.ts
  77. 14 0
      gui/src/2D/controls/line.ts
  78. 29 0
      gui/src/2D/controls/multiLine.ts
  79. 13 0
      gui/src/2D/controls/radioButton.ts
  80. 8 1
      gui/src/2D/controls/rectangle.ts
  81. 19 3
      gui/src/2D/controls/slider.ts
  82. 10 0
      gui/src/2D/controls/stackPanel.ts
  83. 3 0
      gui/src/2D/controls/textBlock.ts
  84. 48 0
      gui/src/2D/controls/virtualKeyboard.ts
  85. 87 3
      gui/src/2D/math2D.ts
  86. 32 1
      gui/src/2D/measure.ts
  87. 18 0
      gui/src/2D/multiLinePoint.ts
  88. 15 0
      gui/src/2D/style.ts
  89. 44 1
      gui/src/2D/valueAndUnit.ts
  90. 67 4
      gui/src/3D/controls/button3D.ts
  91. 2 1
      gui/src/3D/controls/container3D.ts
  92. 24 16
      gui/src/3D/controls/control3D.ts
  93. 135 16
      gui/src/3D/controls/holographicButton.ts
  94. 3 1
      gui/src/3D/controls/stackPanel3D.ts
  95. 36 2
      gui/src/3D/gui3DManager.ts
  96. 40 4
      gui/src/3D/materials/fluentMaterial.ts
  97. 14 1
      gui/src/3D/materials/shaders/fluent.fragment.fx
  98. 11 1
      gui/src/3D/materials/shaders/fluent.vertex.fx
  99. 11 1
      gui/src/3D/vector3WithInfo.ts
  100. 0 0
      inspector/sass/_detailPanel.scss

+ 1 - 0
.gitignore

@@ -182,3 +182,4 @@ Viewer/dist/viewer.max.js
 Viewer/tests/unit/src/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
+.sass-cache/

File diff suppressed because it is too large
+ 11705 - 10459
Playground/babylon.d.txt


+ 4 - 4
Playground/debug.html

@@ -152,7 +152,7 @@
                 </div>
             </div>
 
-            <div class="button uncheck" id="debugButton1600">Debug layer
+            <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>
@@ -245,7 +245,7 @@
                     <div class="option" id="minimapToggle1475">Minimap
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
-                    <div class="option" id="debugButton1475">Debug layer
+                    <div class="option" id="debugButton1475">Inspector
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                     <div class="option" id="metadataButton1475">Metadata</div>
@@ -332,7 +332,7 @@
                     <div class="option" id="minimapToggle1030">Minimap
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
-                    <div class="option" id="debugButton1030">Debug layer
+                    <div class="option" id="debugButton1030">Inspector
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                     <div class="option" id="metadataButton1030">Metadata</div>
@@ -416,7 +416,7 @@
                     <div class="option" id="minimapToggle750">Minimap
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
-                    <div class="option" id="debugButton750">Debug layer
+                    <div class="option" id="debugButton750">Inspector
                         <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                     <div class="option" id="metadataButton750">Metadata</div>

+ 4 - 4
Playground/index-local.html

@@ -95,7 +95,7 @@
                     </div>
                 </div>
 
-                <div class="button uncheck" id="debugButton1600">Debug layer
+                <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>
@@ -187,7 +187,7 @@
                         <div class="option" id="minimapToggle1475">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1475">Debug layer
+                        <div class="option" id="debugButton1475">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1475">Metadata</div>
@@ -274,7 +274,7 @@
                         <div class="option" id="minimapToggle1030">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1030">Debug layer
+                        <div class="option" id="debugButton1030">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1030">Metadata</div>
@@ -358,7 +358,7 @@
                         <div class="option" id="minimapToggle750">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton750">Debug layer
+                        <div class="option" id="debugButton750">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton750">Metadata</div>

+ 4 - 4
Playground/index.html

@@ -130,7 +130,7 @@
                     </div>
                 </div>
 
-                <div class="button uncheck" id="debugButton1600">Debug layer
+                <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>
@@ -222,7 +222,7 @@
                         <div class="option" id="minimapToggle1475">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1475">Debug layer
+                        <div class="option" id="debugButton1475">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1475">Metadata</div>
@@ -309,7 +309,7 @@
                         <div class="option" id="minimapToggle1030">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1030">Debug layer
+                        <div class="option" id="debugButton1030">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1030">Metadata</div>
@@ -393,7 +393,7 @@
                         <div class="option" id="minimapToggle750">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton750">Debug layer
+                        <div class="option" id="debugButton750">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton750">Metadata</div>

+ 4 - 4
Playground/indexStable.html

@@ -123,7 +123,7 @@
                     </div>
                 </div>
 
-                <div class="button uncheck" id="debugButton1600">Debug layer
+                <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>
@@ -213,7 +213,7 @@
                         <div class="option" id="minimapToggle1475">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1475">Debug layer
+                        <div class="option" id="debugButton1475">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1475">Metadata</div>
@@ -300,7 +300,7 @@
                         <div class="option" id="minimapToggle1030">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton1030">Debug layer
+                        <div class="option" id="debugButton1030">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton1030">Metadata</div>
@@ -384,7 +384,7 @@
                         <div class="option" id="minimapToggle750">Minimap
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                        <div class="option" id="debugButton750">Debug layer
+                        <div class="option" id="debugButton750">Inspector
                             <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         <div class="option" id="metadataButton750">Metadata</div>

+ 4 - 2
Playground/js/index.js

@@ -458,6 +458,8 @@
 
             } catch (e) {
                 showError(e.message, e);
+                // Also log error in console to help debug playgrounds
+                console.error(e);
             }
         };
         window.addEventListener("resize",
@@ -754,11 +756,11 @@
 
             if (debugButton.classList.contains('uncheck')) {
                 setToMultipleID("debugButton", "removeClass", 'uncheck');
-                setToMultipleID("debugButton", "innerHTML", 'Debug layer<i class="fa fa-check-square" aria-hidden="true"></i>');
+                setToMultipleID("debugButton", "innerHTML", 'Inspector<i class="fa fa-check-square" aria-hidden="true"></i>');
                 scene.debugLayer.show();
             } else {
                 setToMultipleID("debugButton", "addClass", 'uncheck');
-                setToMultipleID("debugButton", "innerHTML", 'Debug layer<i class="fa fa-square-o" aria-hidden="true"></i>');
+                setToMultipleID("debugButton", "innerHTML", 'Inspector<i class="fa fa-square-o" aria-hidden="true"></i>');
                 scene.debugLayer.hide();
             }
         }

BIN
Playground/textures/colorGrade-highContrast.png


BIN
Playground/textures/colorGrade-inverted.png


BIN
Playground/textures/colorGrade-posterize.png


BIN
Playground/textures/down.png


BIN
Playground/textures/up.png


+ 28 - 7
Tools/Gulp/config.json

@@ -95,6 +95,8 @@
             "physics",
             "textureFormats",
             "debug",
+            "utilityLayer",
+            "gizmos",
             "morphTargets",
             "octrees",
             "vr",
@@ -1020,11 +1022,7 @@
                 "../../src/Debug/babylon.rayHelper.js",
                 "../../src/Debug/babylon.debugLayer.js",
                 "../../src/Debug/babylon.physicsViewer.js",
-                "../../src/Rendering/babylon.boundingBoxRenderer.js",
-                "../../src/Rendering/babylon.utilityLayerRenderer.js",
-                "../../src/Gizmos/babylon.gizmo.js",
-                "../../src/Gizmos/babylon.axisDragGizmo.js",
-                "../../src/Gizmos/babylon.positionGizmo.js"
+                "../../src/Rendering/babylon.boundingBoxRenderer.js"
             ],
             "dependUpon": [
                 "shaderMaterial",
@@ -1035,6 +1033,31 @@
             ],
             "shaders": []
         },
+        "utilityLayer": {
+            "files": [
+                "../../src/Rendering/babylon.utilityLayerRenderer.js"
+            ],
+            "dependUpon": [
+                "core"
+            ]
+        },
+        "gizmos": {
+            "files": [
+                "../../src/Gizmos/babylon.gizmo.js",
+                "../../src/Gizmos/babylon.axisDragGizmo.js",
+                "../../src/Gizmos/babylon.axisScaleGizmo.js",
+                "../../src/Gizmos/babylon.planeRotationGizmo.js",
+                "../../src/Gizmos/babylon.positionGizmo.js",
+                "../../src/Gizmos/babylon.rotationGizmo.js",
+                "../../src/Gizmos/babylon.scaleGizmo.js",
+                "../../src/Gizmos/babylon.gizmoManager.js"
+            ],
+            "dependUpon": [
+                "core",
+                "utilityLayer",
+                "meshBehaviors"
+            ]
+        },
         "morphTargets": {
             "files": [
                 "../../src/Morph/babylon.morphTarget.js",
@@ -1560,7 +1583,6 @@
             {
                 "files": [
                     "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
@@ -1585,7 +1607,6 @@
                     "../../loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts",
                     "../../loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",

+ 11 - 1
Tools/Gulp/gulp-validateTypedoc.js

@@ -223,7 +223,9 @@ Validate.prototype.add = function (filePath, content) {
     var json = JSON.parse(contentString);
 
     this.validateTypedoc(json);
-    this.results.errors += this.results[this.filePath].errors;
+    if (this.results[this.filePath]) {
+        this.results.errors += this.results[this.filePath].errors;
+    }
 }
 
 Validate.prototype.getResults = function () {
@@ -270,6 +272,14 @@ Validate.prototype.validateTypedocNamespaces = function (namespaces) {
         return;
     }
 
+    // Check first sub module like BABYLON.Debug or BABYLON.GUI
+    if (namespace.children && namespace.children.length > 0) {
+        var firstChild = namespace.children[0];
+        if (firstChild.kindString === "Module") {
+            namespace = firstChild;
+        }
+    }
+
     // Validate Classes
     for (var a in namespace.children) {
         containerNode = namespace.children[a];

+ 4 - 2
Tools/Gulp/gulpfile.js

@@ -898,7 +898,9 @@ gulp.task("modules", ["prepare-dependency-tree"], function () {
  */
 gulp.task("typedoc-generate", function () {
     return gulp
-        .src(["../../dist/preview release/babylon.d.ts",
+        .src([
+            "../../dist/preview release/babylon.d.ts",
+            "../../dist/preview release/gui/babylon.gui.d.ts",
             "../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts",
             "../../dist/preview release/serializers/babylon.glTF2Serializer.d.ts",
             "../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"])
@@ -955,7 +957,7 @@ gulp.task("typedoc-all", function (cb) {
  * Validate compile the code and check the comments and style case convention through typedoc
  */
 gulp.task("typedoc-check", function (cb) {
-    runSequence("typescript-compile", "typedoc-generate", "typedoc-validate", cb);
+    runSequence("typescript-compile", "gui", "loaders", "serializers", "typedoc-generate", "typedoc-validate", cb);
 });
 
 /**

File diff suppressed because it is too large
+ 13237 - 13032
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 50 - 49
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 476 - 71
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 476 - 71
dist/preview release/babylon.no-module.max.js


File diff suppressed because it is too large
+ 50 - 49
dist/preview release/babylon.worker.js


File diff suppressed because it is too large
+ 478 - 73
dist/preview release/es6.js


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

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

File diff suppressed because it is too large
+ 1012 - 27
dist/preview release/gui/babylon.gui.d.ts


File diff suppressed because it is too large
+ 1201 - 57
dist/preview release/gui/babylon.gui.js


File diff suppressed because it is too large
+ 5 - 4
dist/preview release/gui/babylon.gui.min.js


File diff suppressed because it is too large
+ 1012 - 27
dist/preview release/gui/babylon.gui.module.d.ts


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

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

File diff suppressed because it is too large
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


+ 34 - 30
dist/preview release/inspector/babylon.inspector.css

@@ -1,7 +1,7 @@
-@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css);
+@import url(https://use.fontawesome.com/releases/v5.0.13/css/all.css);
 @import url(https://fonts.googleapis.com/css?family=Inconsolata);
 
-@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css);
+@import url(https://use.fontawesome.com/releases/v5.0.13/css/all.css);
 @import url(https://fonts.googleapis.com/css?family=Inconsolata);
 .insp-wrapper {
   user-select: none;
@@ -44,11 +44,11 @@
       font-size: 1em; }
       .insp-wrapper .insp-right-panel .top-panel .tab-panel-content {
         width: 100%;
-        height: calc(100% - 40px); }
+        height: calc(100% - 50px); }
       .insp-wrapper .insp-right-panel .top-panel .more-tabs-panel {
         position: absolute;
         z-index: 10;
-        top: 40px;
+        top: 50px;
         right: 0;
         width: 100px;
         display: none;
@@ -70,7 +70,7 @@
             background-color: #454545; }
   .insp-wrapper .tooltip {
     position: absolute;
-    top: 40px;
+    top: 50px;
     right: 0;
     color: #f29766;
     display: none;
@@ -115,15 +115,15 @@
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
-        content: "\f10c";
+        font-family: "Font Awesome 5 Free", sans-serif;
+        content: "\f111";
         margin-right: 10px; }
       .insp-wrapper .tab-panel .scene-actions .action-radio.active:before {
         width: 1em;
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
+        font-family: "Font Awesome 5 Free", sans-serif;
         content: "\f192";
         color: #5db0d7;
         margin-right: 10px; }
@@ -132,15 +132,15 @@
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
-        content: "\f096";
+        font-family: "Font Awesome 5 Free", sans-serif;
+        content: "\f0c8";
         margin-right: 10px; }
       .insp-wrapper .tab-panel .scene-actions .action.active:before {
         width: 1em;
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
+        font-family: "Font Awesome 5 Free", sans-serif;
         content: "\f14a";
         color: #5db0d7;
         margin-right: 10px; }
@@ -263,15 +263,15 @@
       height: 1em;
       line-height: 1em;
       display: inline-block;
-      font-family: 'FontAwesome', sans-serif;
-      content: "\f096";
+      font-family: "Font Awesome 5 Free", sans-serif;
+      content: "\f0c8";
       margin-right: 10px; }
     .insp-wrapper .tab-panel .gltf-actions .gltf-checkbox.active:before {
       width: 1em;
       height: 1em;
       line-height: 1em;
       display: inline-block;
-      font-family: 'FontAwesome', sans-serif;
+      font-family: "Font Awesome 5 Free", sans-serif;
       content: "\f14a";
       color: #5db0d7;
       margin-right: 10px; }
@@ -304,7 +304,7 @@
   .insp-wrapper .insp-tree {
     overflow-y: auto;
     overflow-x: hidden;
-    height: calc(50% - 40px - 30px); }
+    height: calc(50% - 50px - 30px); }
     .insp-wrapper .insp-tree .line {
       padding: 3px;
       cursor: pointer; }
@@ -319,15 +319,17 @@
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
-        content: "\f078"; }
+        font-family: "Font Awesome 5 Free", sans-serif;
+        content: "\f107";
+        font-weight: 900; }
       .insp-wrapper .insp-tree .line.folded:before {
         width: 1em;
         height: 1em;
         line-height: 1em;
         display: inline-block;
-        font-family: 'FontAwesome', sans-serif;
-        content: "\f054"; }
+        font-family: "Font Awesome 5 Free", sans-serif;
+        content: "\f105";
+        font-weight: 900; }
       .insp-wrapper .insp-tree .line.unfolded.transformNode > span:first-of-type {
         color: #f29766; }
       .insp-wrapper .insp-tree .line.folded.transformNode > span:first-of-type {
@@ -366,13 +368,15 @@
           .insp-wrapper .insp-details .base-row .prop-value.clickable:hover, .insp-wrapper .insp-details .row .prop-value.clickable:hover, .insp-wrapper .insp-details .header-row .prop-value.clickable:hover {
             background-color: #383838; }
           .insp-wrapper .insp-details .base-row .prop-value.clickable:after, .insp-wrapper .insp-details .row .prop-value.clickable:after, .insp-wrapper .insp-details .header-row .prop-value.clickable:after {
-            font-family: 'FontAwesome', sans-serif;
-            content: "\00a0 \00a0 \00a0 \f054"; }
+            font-family: "Font Awesome 5 Free", sans-serif;
+            content: "\00a0 \00a0 \00a0 \f105";
+            font-weight: 900; }
     .insp-wrapper .insp-details .row:nth-child(even) {
       background-color: #2c2c2c; }
     .insp-wrapper .insp-details .row.unfolded .prop-value.clickable:after {
-      font-family: 'FontAwesome', sans-serif;
-      content: "\00a0 \00a0 \00a0 \f078"; }
+      font-family: "Font Awesome 5 Free", sans-serif;
+      content: "\00a0 \00a0 \00a0 \f107";
+      font-weight: 900; }
     .insp-wrapper .insp-details .header-row {
       background-color: #2c2c2c;
       color: #ccc;
@@ -423,7 +427,7 @@
           max-width: 110px;
           max-height: 110px; }
   .insp-wrapper .tabbar {
-    height: 40px;
+    height: 50px;
     display: flex;
     align-items: center;
     border-bottom: 1px solid #383838;
@@ -432,11 +436,11 @@
     overflow-y: hidden;
     box-sizing: border-box; }
     .insp-wrapper .tabbar .tab {
-      height: calc(40px - 2px);
+      height: calc(50px - 2px);
       width: auto;
       padding: 0 10px 0 10px;
       color: #ccc;
-      line-height: 40px;
+      line-height: 50px;
       text-align: center;
       cursor: pointer;
       margin: 0 5px 0 5px;
@@ -449,8 +453,8 @@
       .insp-wrapper .tabbar .tab.active {
         border-bottom: 1px solid #f29766; }
     .insp-wrapper .tabbar .more-tabs {
-      width: 40px;
-      height: 40px;
+      width: 50px;
+      height: 50px;
       display: flex;
       justify-content: center;
       align-items: center;
@@ -467,8 +471,8 @@
   .insp-wrapper .toolbar {
     display: flex; }
     .insp-wrapper .toolbar .tool {
-      width: 40px;
-      height: 40px;
+      width: 50px;
+      height: 50px;
       display: flex;
       justify-content: center;
       align-items: center;

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

@@ -1037,6 +1037,7 @@ declare module INSPECTOR {
         private _actions;
         private _detailsPanel;
         private _split;
+        static readonly IsSupported: boolean;
         /** @hidden */
         static _Initialize(): void;
         constructor(tabbar: TabBar, inspector: Inspector);

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

@@ -146,10 +146,14 @@ var INSPECTOR;
                 INSPECTOR.Helpers.SEND_EVENT('resize');
                 this._tabbar.updateWidth();
             }
-            // Refresh the inspector if the browser is not edge
-            if (!INSPECTOR.Helpers.IsBrowserEdge()) {
-                this.refresh();
-            }
+            /*
+            * Refresh the inspector if the browser is not edge
+            *   Why not ?! Condition commented on 180525
+            *   To be tested
+            */
+            // if (!Helpers.IsBrowserEdge()) {
+            this.refresh();
+            // }
             // Check custom css colors
             if (newColors) {
                 var bColor = newColors.backgroundColor || '#242424';
@@ -297,52 +301,48 @@ var INSPECTOR;
          */
         Inspector.prototype.openPopup = function (firstTime) {
             var _this = this;
-            if (INSPECTOR.Helpers.IsBrowserEdge()) {
-                console.warn('Inspector - Popup mode is disabled in Edge, as the popup DOM cannot be updated from the main window for security reasons');
+            // Create popup
+            var popup = window.open('', 'Babylon.js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
+            if (!popup) {
+                return;
             }
-            else {
-                // Create popup
-                var popup = window.open('', 'Babylon.js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
-                if (!popup) {
-                    return;
-                }
-                popup.document.title = 'Babylon.js INSPECTOR';
-                // Get the inspector style      
-                var styles = Inspector.DOCUMENT.querySelectorAll('style');
-                for (var s = 0; s < styles.length; s++) {
-                    popup.document.body.appendChild(styles[s].cloneNode(true));
+            popup.document.title = "Babylon.js INSPECTOR";
+            popup.document.body.innerHTML = "Coucou!";
+            // Get the inspector style      
+            var styles = Inspector.DOCUMENT.querySelectorAll('style');
+            for (var s = 0; s < styles.length; s++) {
+                popup.document.body.appendChild(styles[s].cloneNode(true));
+            }
+            var links = document.querySelectorAll('link');
+            for (var l = 0; l < links.length; l++) {
+                var link = popup.document.createElement("link");
+                link.rel = "stylesheet";
+                link.href = links[l].href;
+                popup.document.head.appendChild(link);
+            }
+            // Dispose the right panel if existing
+            if (!firstTime) {
+                this.dispose();
+            }
+            // set the mode as popup
+            this._popupMode = true;
+            // Save the HTML document
+            Inspector.DOCUMENT = popup.document;
+            Inspector.WINDOW = popup;
+            // Build the inspector wrapper
+            this._c2diwrapper = INSPECTOR.Helpers.CreateDiv('insp-wrapper', popup.document.body);
+            // add inspector     
+            var inspector = INSPECTOR.Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+            inspector.classList.add('popupmode');
+            // and build it in the popup  
+            this._buildInspector(inspector);
+            // Rebuild it
+            this.refresh();
+            popup.addEventListener('resize', function () {
+                if (_this._tabbar) {
+                    _this._tabbar.updateWidth();
                 }
-                var links = document.querySelectorAll('link');
-                for (var l = 0; l < links.length; l++) {
-                    var link = popup.document.createElement("link");
-                    link.rel = "stylesheet";
-                    link.href = links[l].href;
-                    popup.document.head.appendChild(link);
-                }
-                // Dispose the right panel if existing
-                if (!firstTime) {
-                    this.dispose();
-                }
-                // set the mode as popup
-                this._popupMode = true;
-                // Save the HTML document
-                Inspector.DOCUMENT = popup.document;
-                Inspector.WINDOW = popup;
-                // Build the inspector wrapper
-                this._c2diwrapper = INSPECTOR.Helpers.CreateDiv('insp-wrapper', popup.document.body);
-                // add inspector     
-                var inspector = INSPECTOR.Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-                inspector.classList.add('popupmode');
-                // and build it in the popup  
-                this._buildInspector(inspector);
-                // Rebuild it
-                this.refresh();
-                popup.addEventListener('resize', function () {
-                    if (_this._tabbar) {
-                        _this._tabbar.updateWidth();
-                    }
-                });
-            }
+            });
         };
         Inspector.prototype.getActiveTabIndex = function () {
             return this._tabbar.getActiveTabIndex();
@@ -4075,10 +4075,21 @@ var INSPECTOR;
             _this._actions.addEventListener('click', function (event) {
                 _this._closeDetailsPanel();
             });
-            _this._addImport();
-            _this._addExport();
+            if (BABYLON.SceneLoader && BABYLON.GLTFFileLoader && BABYLON.GLTF2.GLTFLoader) {
+                _this._addImport();
+            }
+            if (BABYLON.GLTF2Export) {
+                _this._addExport();
+            }
             return _this;
         }
+        Object.defineProperty(GLTFTab, "IsSupported", {
+            get: function () {
+                return !!(BABYLON.SceneLoader && BABYLON.GLTFFileLoader && BABYLON.GLTF2.GLTFLoader) || !!BABYLON.GLTF2Export;
+            },
+            enumerable: true,
+            configurable: true
+        });
         /** @hidden */
         GLTFTab._Initialize = function () {
             // Must register with OnPluginActivatedObservable as early as possible to
@@ -4265,7 +4276,7 @@ var INSPECTOR;
             _this._tabs.push(_this._meshTab);
             _this._tabs.push(new INSPECTOR.LightTab(_this, _this._inspector));
             _this._tabs.push(new INSPECTOR.MaterialTab(_this, _this._inspector));
-            if (BABYLON.GLTF2Export) {
+            if (INSPECTOR.GLTFTab.IsSupported) {
                 _this._tabs.push(new INSPECTOR.GLTFTab(_this, _this._inspector));
             }
             if (BABYLON.GUI) {
@@ -4608,7 +4619,7 @@ var INSPECTOR;
     var PopupTool = /** @class */ (function (_super) {
         __extends(PopupTool, _super);
         function PopupTool(parent, inspector) {
-            return _super.call(this, 'fa-external-link', parent, inspector, 'Open the inspector in a popup') || this;
+            return _super.call(this, 'fa-external-link-alt', parent, inspector, 'Open the inspector in a popup') || this;
         }
         // Action : refresh the whole panel
         PopupTool.prototype.action = function () {
@@ -4634,7 +4645,7 @@ var INSPECTOR;
     var RefreshTool = /** @class */ (function (_super) {
         __extends(RefreshTool, _super);
         function RefreshTool(parent, inspector) {
-            return _super.call(this, 'fa-refresh', parent, inspector, 'Refresh the current tab') || this;
+            return _super.call(this, 'fa-sync', parent, inspector, 'Refresh the current tab') || this;
         }
         // Action : refresh the whole panel
         RefreshTool.prototype.action = function () {

File diff suppressed because it is too large
+ 4 - 4
dist/preview release/inspector/babylon.inspector.min.js


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

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

+ 4 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -164,12 +164,14 @@ declare module BABYLON {
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         /**
          * Factory function that creates a glTF 1.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV1: () => IGLTFLoader;
+        static _CreateGLTFLoaderV1: () => IGLTFLoader;
         /**
          * Factory function that creates a glTF 2.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV2: () => IGLTFLoader;
+        static _CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed
          */

+ 3 - 3
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -389,8 +389,8 @@ var BABYLON;
                 }
             }
             var createLoaders = {
-                1: GLTFFileLoader.CreateGLTFLoaderV1,
-                2: GLTFFileLoader.CreateGLTFLoaderV2
+                1: GLTFFileLoader._CreateGLTFLoaderV1,
+                2: GLTFFileLoader._CreateGLTFLoaderV2
             };
             var createLoader = createLoaders[version.major];
             if (!createLoader) {
@@ -2208,7 +2208,7 @@ var BABYLON;
         }());
         GLTF1.GLTFLoader = GLTFLoader;
         ;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
     })(GLTF1 = BABYLON.GLTF1 || (BABYLON.GLTF1 = {}));
 })(BABYLON || (BABYLON = {}));
 

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 87 - 38
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -164,12 +164,14 @@ declare module BABYLON {
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         /**
          * Factory function that creates a glTF 1.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV1: () => IGLTFLoader;
+        static _CreateGLTFLoaderV1: () => IGLTFLoader;
         /**
          * Factory function that creates a glTF 2.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV2: () => IGLTFLoader;
+        static _CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed
          */
@@ -370,22 +372,13 @@ declare module BABYLON {
 }
 
 
+
 declare module BABYLON.GLTF2 {
     /** @hidden */
     interface _IArrayItem {
         _index: number;
     }
     /** @hidden */
-    class _ArrayItem {
-        /** @hidden */
-        static Assign(values?: _IArrayItem[]): void;
-    }
-}
-
-
-
-declare module BABYLON.GLTF2 {
-    /** @hidden */
     interface _ILoaderAccessor extends IAccessor, _IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
@@ -401,7 +394,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderAnimationSampler extends IAnimationSampler, _IArrayItem {
-        _data: Promise<_ILoaderAnimationSamplerData>;
+        _data?: Promise<_ILoaderAnimationSamplerData>;
     }
     /** @hidden */
     interface _ILoaderAnimation extends IAnimation, _IArrayItem {
@@ -444,7 +437,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderNode extends INode, _IArrayItem {
-        _parent: _ILoaderNode;
+        _parent?: _ILoaderNode;
         _babylonMesh?: Mesh;
         _primitiveBabylonMeshes?: Mesh[];
         _babylonBones?: Bone[];
@@ -660,7 +653,7 @@ declare module BABYLON.GLTF2 {
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         /** @hidden */
-        _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
         /** @hidden */
         _createMaterial(name: string, drawMode: number): PBRMaterial;
         /** @hidden */
@@ -696,36 +689,93 @@ declare module BABYLON.GLTF2 {
      * Abstract class that can be implemented to extend existing glTF loader behavior.
      */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
+        /**
+         * Creates new GLTFLoaderExtension
+         * @param loader defines the GLTFLoader to use
+         */
         constructor(loader: GLTFLoader);
+        /**
+         * Release all resources
+         */
         dispose(): void;
-        /** Override this method to modify the default behavior for loading scenes. */
+        /**
+         * Override this method to modify the default behavior for loading scenes.
+         * @hidden
+         */
         protected _loadSceneAsync(context: string, node: _ILoaderScene): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading nodes. */
+        /**
+         * Override this method to modify the default behavior for loading nodes.
+         * @hidden
+         */
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+        /**
+         * Override this method to modify the default behavior for loading mesh primitive vertex data.
+         * @hidden
+         */
         protected _loadVertexDataAsync(context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Override this method to modify the default behavior for loading materials. */
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading textures. */
+        /**
+         * Override this method to modify the default behavior for loading materials.
+         * @hidden
+         */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Override this method to modify the default behavior for loading textures.
+         * @hidden
+         */
         protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading uris. */
+        /**
+         * Override this method to modify the default behavior for loading uris.
+         * @hidden
+         */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
-        /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
-        /** Helper method called by the loader to allow extensions to override loading scenes. */
+        /**
+         * Helper method called by a loader extension to load an glTF extension.
+         * @hidden
+         */
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading scenes.
+         * @hidden
+         */
+        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 to allow extensions to override loading scenes.
+         * @hidden
+         */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading nodes. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading nodes.
+         * @hidden
+         */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+         * @hidden
+         */
         static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Helper method called by the loader to allow extensions to override loading materials. */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading textures. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading materials.
+         * @hidden
+         */
+        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading textures.
+         * @hidden
+         */
         static _LoadTextureAsync(loader: GLTFLoader, context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading uris. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading uris.
+         * @hidden
+         */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
     }
 }
@@ -767,7 +817,7 @@ declare module BABYLON.GLTF2.Extensions {
         constructor(loader: GLTFLoader);
         dispose(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         /**
          * Gets an array of LOD properties from lowest to highest.
@@ -781,8 +831,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_minecraftMesh extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -791,8 +840,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -817,7 +865,8 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /** @hidden */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -829,7 +878,7 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
     }
 }

+ 165 - 107
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -389,8 +389,8 @@ var BABYLON;
                 }
             }
             var createLoaders = {
-                1: GLTFFileLoader.CreateGLTFLoaderV1,
-                2: GLTFFileLoader.CreateGLTFLoaderV2
+                1: GLTFFileLoader._CreateGLTFLoaderV1,
+                2: GLTFFileLoader._CreateGLTFLoaderV2
             };
             var createLoader = createLoaders[version.major];
             if (!createLoader) {
@@ -591,15 +591,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFFileLoader.js.map
 
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"/>
+
+//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
+
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/**
+ * Defines the module used to import/export glTF 2.0 assets
+ */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        /** @hidden */
         var _ArrayItem = /** @class */ (function () {
             function _ArrayItem() {
             }
-            /** @hidden */
             _ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -609,25 +615,6 @@ var BABYLON;
             };
             return _ArrayItem;
         }());
-        GLTF2._ArrayItem = _ArrayItem;
-    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
-})(BABYLON || (BABYLON = {}));
-
-//# sourceMappingURL=babylon.glTFLoaderUtilities.js.map
-
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-/// <reference path="../../../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"/>
-
-//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
-
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-/**
- * Defines the module used to import/export glTF 2.0 assets
- */
-var BABYLON;
-(function (BABYLON) {
-    var GLTF2;
-    (function (GLTF2) {
         /**
          * Loader for loading a glTF 2.0 asset
          */
@@ -873,19 +860,19 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._setupData = function () {
-                GLTF2._ArrayItem.Assign(this._gltf.accessors);
-                GLTF2._ArrayItem.Assign(this._gltf.animations);
-                GLTF2._ArrayItem.Assign(this._gltf.buffers);
-                GLTF2._ArrayItem.Assign(this._gltf.bufferViews);
-                GLTF2._ArrayItem.Assign(this._gltf.cameras);
-                GLTF2._ArrayItem.Assign(this._gltf.images);
-                GLTF2._ArrayItem.Assign(this._gltf.materials);
-                GLTF2._ArrayItem.Assign(this._gltf.meshes);
-                GLTF2._ArrayItem.Assign(this._gltf.nodes);
-                GLTF2._ArrayItem.Assign(this._gltf.samplers);
-                GLTF2._ArrayItem.Assign(this._gltf.scenes);
-                GLTF2._ArrayItem.Assign(this._gltf.skins);
-                GLTF2._ArrayItem.Assign(this._gltf.textures);
+                _ArrayItem.Assign(this._gltf.accessors);
+                _ArrayItem.Assign(this._gltf.animations);
+                _ArrayItem.Assign(this._gltf.buffers);
+                _ArrayItem.Assign(this._gltf.bufferViews);
+                _ArrayItem.Assign(this._gltf.cameras);
+                _ArrayItem.Assign(this._gltf.images);
+                _ArrayItem.Assign(this._gltf.materials);
+                _ArrayItem.Assign(this._gltf.meshes);
+                _ArrayItem.Assign(this._gltf.nodes);
+                _ArrayItem.Assign(this._gltf.samplers);
+                _ArrayItem.Assign(this._gltf.scenes);
+                _ArrayItem.Assign(this._gltf.skins);
+                _ArrayItem.Assign(this._gltf.textures);
                 if (this._gltf.nodes) {
                     var nodeParents = {};
                     for (var _i = 0, _a = this._gltf.nodes; _i < _a.length; _i++) {
@@ -1068,7 +1055,7 @@ var BABYLON;
                     throw new Error(context + ": Invalid recursive node hierarchy");
                 }
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent._babylonMesh);
+                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
                 node._babylonMesh = babylonMesh;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
@@ -1096,7 +1083,7 @@ var BABYLON;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
-                GLTF2._ArrayItem.Assign(primitives);
+                _ArrayItem.Assign(primitives);
                 if (primitives.length === 1) {
                     var primitive = primitives[0];
                     promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
@@ -1136,7 +1123,7 @@ var BABYLON;
                 }
                 else {
                     var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
-                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
@@ -1327,7 +1314,7 @@ var BABYLON;
                     return babylonBone;
                 }
                 var babylonParentBone = null;
-                if (node._parent._babylonMesh !== this._rootBabylonMesh) {
+                if (node._parent && node._parent._babylonMesh !== this._rootBabylonMesh) {
                     babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
                 var boneIndex = skin.joints.indexOf(node._index);
@@ -1417,8 +1404,8 @@ var BABYLON;
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
-                GLTF2._ArrayItem.Assign(animation.channels);
-                GLTF2._ArrayItem.Assign(animation.samplers);
+                _ArrayItem.Assign(animation.channels);
+                _ArrayItem.Assign(animation.samplers);
                 for (var _i = 0, _a = animation.channels; _i < _a.length; _i++) {
                     var channel = _a[_i];
                     promises.push(this._loadAnimationChannelAsync(context + "/channels/" + channel._index, context, animation, channel, babylonAnimationGroup));
@@ -1772,8 +1759,8 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             /** @hidden */
-            GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
-                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
+            GLTFLoader.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
                     return promise;
                 }
@@ -1781,7 +1768,7 @@ var BABYLON;
                 var babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
                     var promises = new Array();
-                    var name_3 = material.name || "materialSG_" + material._index;
+                    var name_3 = material.name || "material_" + material._index;
                     var babylonMaterial = this._createMaterial(name_3, babylonDrawMode);
                     promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
                     promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
@@ -2174,7 +2161,7 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTF2.GLTFLoader = GLTFLoader;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -2189,28 +2176,59 @@ var BABYLON;
          * Abstract class that can be implemented to extend existing glTF loader behavior.
          */
         var GLTFLoaderExtension = /** @class */ (function () {
+            /**
+             * Creates new GLTFLoaderExtension
+             * @param loader defines the GLTFLoader to use
+             */
             function GLTFLoaderExtension(loader) {
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
             // #region Overridable Methods
-            /** Override this method to modify the default behavior for loading scenes. */
+            /**
+             * Override this method to modify the default behavior for loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadSceneAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading nodes. */
+            /**
+             * Override this method to modify the default behavior for loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadNodeAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+            /**
+             * Override this method to modify the default behavior for loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { return null; };
-            /** Override this method to modify the default behavior for loading materials. */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
-            /** Override this method to modify the default behavior for loading textures. */
+            /**
+             * Override this method to modify the default behavior for loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
+            /**
+             * Override this method to modify the default behavior for loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadTextureAsync = function (context, textureInfo, assign) { return null; };
-            /** Override this method to modify the default behavior for loading uris. */
+            /**
+             * Override this method to modify the default behavior for loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             // #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.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadExtensionAsync = function (context, property, actionAsync) {
                 if (!property.extensions) {
                     return null;
@@ -2220,7 +2238,7 @@ var BABYLON;
                 if (!extension) {
                     return null;
                 }
-                // Clear out the extension before executing the action to avoid recursing into the same property.
+                // Clear out the extension before executing the action to avoid infinite recursion.
                 delete extensions[this.name];
                 try {
                     return actionAsync(context + "/extensions/" + this.name, extension);
@@ -2230,27 +2248,68 @@ var BABYLON;
                     extensions[this.name] = extension;
                 }
             };
-            /** 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
+             */
+            GLTFLoaderExtension.prototype._loadExtrasValueAsync = function (context, property, actionAsync) {
+                if (!property.extras) {
+                    return null;
+                }
+                var extras = property.extras;
+                var value = extras[this.name];
+                if (value === undefined) {
+                    return null;
+                }
+                // Clear out the extras value before executing the action to avoid infinite recursion.
+                delete extras[this.name];
+                try {
+                    return actionAsync(context + "/extras/" + this.name, value);
+                }
+                finally {
+                    // Restore the extras value after executing the action.
+                    extras[this.name] = value;
+                }
+            };
+            /**
+             * Helper method called by the loader to allow extensions to override loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadSceneAsync = function (loader, context, scene) {
                 return loader._applyExtensions(function (extension) { return extension._loadSceneAsync(context, scene); });
             };
-            /** Helper method called by the loader to allow extensions to override loading nodes. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadNodeAsync = function (loader, context, node) {
                 return loader._applyExtensions(function (extension) { return extension._loadNodeAsync(context, node); });
             };
-            /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadVertexDataAsync = function (loader, context, primitive, babylonMesh) {
                 return loader._applyExtensions(function (extension) { return extension._loadVertexDataAsync(context, primitive, babylonMesh); });
             };
-            /** Helper method called by the loader to allow extensions to override loading materials. */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            /**
+             * Helper method called by the loader to allow extensions to override loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading textures. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadTextureAsync = function (loader, context, textureInfo, assign) {
                 return loader._applyExtensions(function (extension) { return extension._loadTextureAsync(context, textureInfo, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading uris. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
@@ -2384,7 +2443,7 @@ var BABYLON;
                         return firstPromise;
                     });
                 };
-                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     // Don't load material LODs if already loading a node LOD.
                     if (this._loadingNodeLOD) {
@@ -2401,7 +2460,7 @@ var BABYLON;
                                     _this._loadMaterialSignals[materialLOD._index] = new BABYLON.Deferred();
                                 }
                             }
-                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
+                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, mesh, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     var babylonDataLOD = materialLOD._babylonData;
                                     assign(babylonDataLOD[babylonDrawMode].material);
@@ -2500,29 +2559,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_minecraftMesh = /** @class */ (function (_super) {
                 __extends(MSFT_minecraftMesh, _super);
-                function MSFT_minecraftMesh(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_minecraftMesh() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (material.needAlphaBlending()) {
-                            material.forceDepthWrite = true;
-                            material.separateCullingPass = true;
-                        }
-                        material.backFaceCulling = material.forceDepthWrite;
-                        material.twoSidedLighting = true;
-                    };
-                    var meshes = loader._gltf.meshes;
-                    if (meshes && meshes.length) {
-                        for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
-                            var mesh = meshes_1[_i];
-                            if (mesh && mesh.extras && mesh.extras.MSFT_minecraftMesh) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_minecraftMesh.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, mesh, function (extensionContext, value) {
+                        if (value) {
+                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                                if (babylonMaterial.needAlphaBlending()) {
+                                    babylonMaterial.forceDepthWrite = true;
+                                    babylonMaterial.separateCullingPass = true;
+                                }
+                                babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite;
+                                babylonMaterial.twoSidedLighting = true;
+                                assign(babylonMaterial);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_minecraftMesh;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_minecraftMesh = MSFT_minecraftMesh;
@@ -2554,29 +2612,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_sRGBFactors = /** @class */ (function (_super) {
                 __extends(MSFT_sRGBFactors, _super);
-                function MSFT_sRGBFactors(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_sRGBFactors() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (!material.albedoTexture) {
-                            material.albedoColor.toLinearSpaceToRef(material.albedoColor);
-                        }
-                        if (!material.reflectivityTexture) {
-                            material.reflectivityColor.toLinearSpaceToRef(material.reflectivityColor);
-                        }
-                    };
-                    var materials = loader._gltf.materials;
-                    if (materials && materials.length) {
-                        for (var _i = 0, materials_1 = materials; _i < materials_1.length; _i++) {
-                            var material = materials_1[_i];
-                            if (material && material.extras && material.extras.MSFT_sRGBFactors) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, material, function (extensionContext, 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);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -2715,7 +2772,8 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                /** @hidden */
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
@@ -2803,7 +2861,7 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function () {
                         material._babylonData = material._babylonData || {};

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 87 - 38
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -164,12 +164,14 @@ declare module BABYLON {
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         /**
          * Factory function that creates a glTF 1.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV1: () => IGLTFLoader;
+        static _CreateGLTFLoaderV1: () => IGLTFLoader;
         /**
          * Factory function that creates a glTF 2.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV2: () => IGLTFLoader;
+        static _CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed
          */
@@ -947,22 +949,13 @@ declare module BABYLON.GLTF1 {
 }
 
 
+
 declare module BABYLON.GLTF2 {
     /** @hidden */
     interface _IArrayItem {
         _index: number;
     }
     /** @hidden */
-    class _ArrayItem {
-        /** @hidden */
-        static Assign(values?: _IArrayItem[]): void;
-    }
-}
-
-
-
-declare module BABYLON.GLTF2 {
-    /** @hidden */
     interface _ILoaderAccessor extends IAccessor, _IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
@@ -978,7 +971,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderAnimationSampler extends IAnimationSampler, _IArrayItem {
-        _data: Promise<_ILoaderAnimationSamplerData>;
+        _data?: Promise<_ILoaderAnimationSamplerData>;
     }
     /** @hidden */
     interface _ILoaderAnimation extends IAnimation, _IArrayItem {
@@ -1021,7 +1014,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderNode extends INode, _IArrayItem {
-        _parent: _ILoaderNode;
+        _parent?: _ILoaderNode;
         _babylonMesh?: Mesh;
         _primitiveBabylonMeshes?: Mesh[];
         _babylonBones?: Bone[];
@@ -1237,7 +1230,7 @@ declare module BABYLON.GLTF2 {
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         /** @hidden */
-        _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
         /** @hidden */
         _createMaterial(name: string, drawMode: number): PBRMaterial;
         /** @hidden */
@@ -1273,36 +1266,93 @@ declare module BABYLON.GLTF2 {
      * Abstract class that can be implemented to extend existing glTF loader behavior.
      */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
+        /**
+         * Creates new GLTFLoaderExtension
+         * @param loader defines the GLTFLoader to use
+         */
         constructor(loader: GLTFLoader);
+        /**
+         * Release all resources
+         */
         dispose(): void;
-        /** Override this method to modify the default behavior for loading scenes. */
+        /**
+         * Override this method to modify the default behavior for loading scenes.
+         * @hidden
+         */
         protected _loadSceneAsync(context: string, node: _ILoaderScene): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading nodes. */
+        /**
+         * Override this method to modify the default behavior for loading nodes.
+         * @hidden
+         */
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+        /**
+         * Override this method to modify the default behavior for loading mesh primitive vertex data.
+         * @hidden
+         */
         protected _loadVertexDataAsync(context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Override this method to modify the default behavior for loading materials. */
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading textures. */
+        /**
+         * Override this method to modify the default behavior for loading materials.
+         * @hidden
+         */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Override this method to modify the default behavior for loading textures.
+         * @hidden
+         */
         protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading uris. */
+        /**
+         * Override this method to modify the default behavior for loading uris.
+         * @hidden
+         */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
-        /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
-        /** Helper method called by the loader to allow extensions to override loading scenes. */
+        /**
+         * Helper method called by a loader extension to load an glTF extension.
+         * @hidden
+         */
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading scenes.
+         * @hidden
+         */
+        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 to allow extensions to override loading scenes.
+         * @hidden
+         */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading nodes. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading nodes.
+         * @hidden
+         */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+         * @hidden
+         */
         static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Helper method called by the loader to allow extensions to override loading materials. */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading textures. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading materials.
+         * @hidden
+         */
+        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading textures.
+         * @hidden
+         */
         static _LoadTextureAsync(loader: GLTFLoader, context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading uris. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading uris.
+         * @hidden
+         */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
     }
 }
@@ -1344,7 +1394,7 @@ declare module BABYLON.GLTF2.Extensions {
         constructor(loader: GLTFLoader);
         dispose(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         /**
          * Gets an array of LOD properties from lowest to highest.
@@ -1358,8 +1408,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_minecraftMesh extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1368,8 +1417,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1394,7 +1442,8 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /** @hidden */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1406,7 +1455,7 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
     }
 }

+ 168 - 108
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -389,8 +389,8 @@ var BABYLON;
                 }
             }
             var createLoaders = {
-                1: GLTFFileLoader.CreateGLTFLoaderV1,
-                2: GLTFFileLoader.CreateGLTFLoaderV2
+                1: GLTFFileLoader._CreateGLTFLoaderV1,
+                2: GLTFFileLoader._CreateGLTFLoaderV2
             };
             var createLoader = createLoaders[version.major];
             if (!createLoader) {
@@ -2208,7 +2208,7 @@ var BABYLON;
         }());
         GLTF1.GLTFLoader = GLTFLoader;
         ;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
     })(GLTF1 = BABYLON.GLTF1 || (BABYLON.GLTF1 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -2807,15 +2807,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFMaterialsCommonExtension.js.map
 
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"/>
+
+//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
+
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/**
+ * Defines the module used to import/export glTF 2.0 assets
+ */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        /** @hidden */
         var _ArrayItem = /** @class */ (function () {
             function _ArrayItem() {
             }
-            /** @hidden */
             _ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -2825,25 +2831,6 @@ var BABYLON;
             };
             return _ArrayItem;
         }());
-        GLTF2._ArrayItem = _ArrayItem;
-    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
-})(BABYLON || (BABYLON = {}));
-
-//# sourceMappingURL=babylon.glTFLoaderUtilities.js.map
-
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-/// <reference path="../../../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"/>
-
-//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
-
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-/**
- * Defines the module used to import/export glTF 2.0 assets
- */
-var BABYLON;
-(function (BABYLON) {
-    var GLTF2;
-    (function (GLTF2) {
         /**
          * Loader for loading a glTF 2.0 asset
          */
@@ -3089,19 +3076,19 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._setupData = function () {
-                GLTF2._ArrayItem.Assign(this._gltf.accessors);
-                GLTF2._ArrayItem.Assign(this._gltf.animations);
-                GLTF2._ArrayItem.Assign(this._gltf.buffers);
-                GLTF2._ArrayItem.Assign(this._gltf.bufferViews);
-                GLTF2._ArrayItem.Assign(this._gltf.cameras);
-                GLTF2._ArrayItem.Assign(this._gltf.images);
-                GLTF2._ArrayItem.Assign(this._gltf.materials);
-                GLTF2._ArrayItem.Assign(this._gltf.meshes);
-                GLTF2._ArrayItem.Assign(this._gltf.nodes);
-                GLTF2._ArrayItem.Assign(this._gltf.samplers);
-                GLTF2._ArrayItem.Assign(this._gltf.scenes);
-                GLTF2._ArrayItem.Assign(this._gltf.skins);
-                GLTF2._ArrayItem.Assign(this._gltf.textures);
+                _ArrayItem.Assign(this._gltf.accessors);
+                _ArrayItem.Assign(this._gltf.animations);
+                _ArrayItem.Assign(this._gltf.buffers);
+                _ArrayItem.Assign(this._gltf.bufferViews);
+                _ArrayItem.Assign(this._gltf.cameras);
+                _ArrayItem.Assign(this._gltf.images);
+                _ArrayItem.Assign(this._gltf.materials);
+                _ArrayItem.Assign(this._gltf.meshes);
+                _ArrayItem.Assign(this._gltf.nodes);
+                _ArrayItem.Assign(this._gltf.samplers);
+                _ArrayItem.Assign(this._gltf.scenes);
+                _ArrayItem.Assign(this._gltf.skins);
+                _ArrayItem.Assign(this._gltf.textures);
                 if (this._gltf.nodes) {
                     var nodeParents = {};
                     for (var _i = 0, _a = this._gltf.nodes; _i < _a.length; _i++) {
@@ -3284,7 +3271,7 @@ var BABYLON;
                     throw new Error(context + ": Invalid recursive node hierarchy");
                 }
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent._babylonMesh);
+                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
                 node._babylonMesh = babylonMesh;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
@@ -3312,7 +3299,7 @@ var BABYLON;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
-                GLTF2._ArrayItem.Assign(primitives);
+                _ArrayItem.Assign(primitives);
                 if (primitives.length === 1) {
                     var primitive = primitives[0];
                     promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
@@ -3352,7 +3339,7 @@ var BABYLON;
                 }
                 else {
                     var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
-                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
@@ -3543,7 +3530,7 @@ var BABYLON;
                     return babylonBone;
                 }
                 var babylonParentBone = null;
-                if (node._parent._babylonMesh !== this._rootBabylonMesh) {
+                if (node._parent && node._parent._babylonMesh !== this._rootBabylonMesh) {
                     babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
                 var boneIndex = skin.joints.indexOf(node._index);
@@ -3633,8 +3620,8 @@ var BABYLON;
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
-                GLTF2._ArrayItem.Assign(animation.channels);
-                GLTF2._ArrayItem.Assign(animation.samplers);
+                _ArrayItem.Assign(animation.channels);
+                _ArrayItem.Assign(animation.samplers);
                 for (var _i = 0, _a = animation.channels; _i < _a.length; _i++) {
                     var channel = _a[_i];
                     promises.push(this._loadAnimationChannelAsync(context + "/channels/" + channel._index, context, animation, channel, babylonAnimationGroup));
@@ -3988,8 +3975,8 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             /** @hidden */
-            GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
-                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
+            GLTFLoader.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
                     return promise;
                 }
@@ -3997,7 +3984,7 @@ var BABYLON;
                 var babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
                     var promises = new Array();
-                    var name_3 = material.name || "materialSG_" + material._index;
+                    var name_3 = material.name || "material_" + material._index;
                     var babylonMaterial = this._createMaterial(name_3, babylonDrawMode);
                     promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
                     promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
@@ -4390,7 +4377,7 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTF2.GLTFLoader = GLTFLoader;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -4405,28 +4392,59 @@ var BABYLON;
          * Abstract class that can be implemented to extend existing glTF loader behavior.
          */
         var GLTFLoaderExtension = /** @class */ (function () {
+            /**
+             * Creates new GLTFLoaderExtension
+             * @param loader defines the GLTFLoader to use
+             */
             function GLTFLoaderExtension(loader) {
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
             // #region Overridable Methods
-            /** Override this method to modify the default behavior for loading scenes. */
+            /**
+             * Override this method to modify the default behavior for loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadSceneAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading nodes. */
+            /**
+             * Override this method to modify the default behavior for loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadNodeAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+            /**
+             * Override this method to modify the default behavior for loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { return null; };
-            /** Override this method to modify the default behavior for loading materials. */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
-            /** Override this method to modify the default behavior for loading textures. */
+            /**
+             * Override this method to modify the default behavior for loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
+            /**
+             * Override this method to modify the default behavior for loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadTextureAsync = function (context, textureInfo, assign) { return null; };
-            /** Override this method to modify the default behavior for loading uris. */
+            /**
+             * Override this method to modify the default behavior for loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             // #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.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadExtensionAsync = function (context, property, actionAsync) {
                 if (!property.extensions) {
                     return null;
@@ -4436,7 +4454,7 @@ var BABYLON;
                 if (!extension) {
                     return null;
                 }
-                // Clear out the extension before executing the action to avoid recursing into the same property.
+                // Clear out the extension before executing the action to avoid infinite recursion.
                 delete extensions[this.name];
                 try {
                     return actionAsync(context + "/extensions/" + this.name, extension);
@@ -4446,27 +4464,68 @@ var BABYLON;
                     extensions[this.name] = extension;
                 }
             };
-            /** 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
+             */
+            GLTFLoaderExtension.prototype._loadExtrasValueAsync = function (context, property, actionAsync) {
+                if (!property.extras) {
+                    return null;
+                }
+                var extras = property.extras;
+                var value = extras[this.name];
+                if (value === undefined) {
+                    return null;
+                }
+                // Clear out the extras value before executing the action to avoid infinite recursion.
+                delete extras[this.name];
+                try {
+                    return actionAsync(context + "/extras/" + this.name, value);
+                }
+                finally {
+                    // Restore the extras value after executing the action.
+                    extras[this.name] = value;
+                }
+            };
+            /**
+             * Helper method called by the loader to allow extensions to override loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadSceneAsync = function (loader, context, scene) {
                 return loader._applyExtensions(function (extension) { return extension._loadSceneAsync(context, scene); });
             };
-            /** Helper method called by the loader to allow extensions to override loading nodes. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadNodeAsync = function (loader, context, node) {
                 return loader._applyExtensions(function (extension) { return extension._loadNodeAsync(context, node); });
             };
-            /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadVertexDataAsync = function (loader, context, primitive, babylonMesh) {
                 return loader._applyExtensions(function (extension) { return extension._loadVertexDataAsync(context, primitive, babylonMesh); });
             };
-            /** Helper method called by the loader to allow extensions to override loading materials. */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            /**
+             * Helper method called by the loader to allow extensions to override loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading textures. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadTextureAsync = function (loader, context, textureInfo, assign) {
                 return loader._applyExtensions(function (extension) { return extension._loadTextureAsync(context, textureInfo, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading uris. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
@@ -4600,7 +4659,7 @@ var BABYLON;
                         return firstPromise;
                     });
                 };
-                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     // Don't load material LODs if already loading a node LOD.
                     if (this._loadingNodeLOD) {
@@ -4617,7 +4676,7 @@ var BABYLON;
                                     _this._loadMaterialSignals[materialLOD._index] = new BABYLON.Deferred();
                                 }
                             }
-                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
+                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, mesh, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     var babylonDataLOD = materialLOD._babylonData;
                                     assign(babylonDataLOD[babylonDrawMode].material);
@@ -4716,29 +4775,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_minecraftMesh = /** @class */ (function (_super) {
                 __extends(MSFT_minecraftMesh, _super);
-                function MSFT_minecraftMesh(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_minecraftMesh() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (material.needAlphaBlending()) {
-                            material.forceDepthWrite = true;
-                            material.separateCullingPass = true;
-                        }
-                        material.backFaceCulling = material.forceDepthWrite;
-                        material.twoSidedLighting = true;
-                    };
-                    var meshes = loader._gltf.meshes;
-                    if (meshes && meshes.length) {
-                        for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
-                            var mesh = meshes_1[_i];
-                            if (mesh && mesh.extras && mesh.extras.MSFT_minecraftMesh) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_minecraftMesh.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, mesh, function (extensionContext, value) {
+                        if (value) {
+                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                                if (babylonMaterial.needAlphaBlending()) {
+                                    babylonMaterial.forceDepthWrite = true;
+                                    babylonMaterial.separateCullingPass = true;
+                                }
+                                babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite;
+                                babylonMaterial.twoSidedLighting = true;
+                                assign(babylonMaterial);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_minecraftMesh;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_minecraftMesh = MSFT_minecraftMesh;
@@ -4770,29 +4828,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_sRGBFactors = /** @class */ (function (_super) {
                 __extends(MSFT_sRGBFactors, _super);
-                function MSFT_sRGBFactors(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_sRGBFactors() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (!material.albedoTexture) {
-                            material.albedoColor.toLinearSpaceToRef(material.albedoColor);
-                        }
-                        if (!material.reflectivityTexture) {
-                            material.reflectivityColor.toLinearSpaceToRef(material.reflectivityColor);
-                        }
-                    };
-                    var materials = loader._gltf.materials;
-                    if (materials && materials.length) {
-                        for (var _i = 0, materials_1 = materials; _i < materials_1.length; _i++) {
-                            var material = materials_1[_i];
-                            if (material && material.extras && material.extras.MSFT_sRGBFactors) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, material, function (extensionContext, 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);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -4931,7 +4988,8 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                /** @hidden */
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
@@ -5019,7 +5077,7 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function () {
                         material._babylonData = material._babylonData || {};
@@ -5077,6 +5135,8 @@ var BABYLON;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
+//# sourceMappingURL=KHR_materials_unlit.js.map
+
 /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 87 - 38
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -260,12 +260,14 @@ declare module BABYLON {
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         /**
          * Factory function that creates a glTF 1.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV1: () => IGLTFLoader;
+        static _CreateGLTFLoaderV1: () => IGLTFLoader;
         /**
          * Factory function that creates a glTF 2.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV2: () => IGLTFLoader;
+        static _CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed
          */
@@ -1043,22 +1045,13 @@ declare module BABYLON.GLTF1 {
 }
 
 
+
 declare module BABYLON.GLTF2 {
     /** @hidden */
     interface _IArrayItem {
         _index: number;
     }
     /** @hidden */
-    class _ArrayItem {
-        /** @hidden */
-        static Assign(values?: _IArrayItem[]): void;
-    }
-}
-
-
-
-declare module BABYLON.GLTF2 {
-    /** @hidden */
     interface _ILoaderAccessor extends IAccessor, _IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
@@ -1074,7 +1067,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderAnimationSampler extends IAnimationSampler, _IArrayItem {
-        _data: Promise<_ILoaderAnimationSamplerData>;
+        _data?: Promise<_ILoaderAnimationSamplerData>;
     }
     /** @hidden */
     interface _ILoaderAnimation extends IAnimation, _IArrayItem {
@@ -1117,7 +1110,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderNode extends INode, _IArrayItem {
-        _parent: _ILoaderNode;
+        _parent?: _ILoaderNode;
         _babylonMesh?: Mesh;
         _primitiveBabylonMeshes?: Mesh[];
         _babylonBones?: Bone[];
@@ -1333,7 +1326,7 @@ declare module BABYLON.GLTF2 {
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         /** @hidden */
-        _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
         /** @hidden */
         _createMaterial(name: string, drawMode: number): PBRMaterial;
         /** @hidden */
@@ -1369,36 +1362,93 @@ declare module BABYLON.GLTF2 {
      * Abstract class that can be implemented to extend existing glTF loader behavior.
      */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
+        /**
+         * Creates new GLTFLoaderExtension
+         * @param loader defines the GLTFLoader to use
+         */
         constructor(loader: GLTFLoader);
+        /**
+         * Release all resources
+         */
         dispose(): void;
-        /** Override this method to modify the default behavior for loading scenes. */
+        /**
+         * Override this method to modify the default behavior for loading scenes.
+         * @hidden
+         */
         protected _loadSceneAsync(context: string, node: _ILoaderScene): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading nodes. */
+        /**
+         * Override this method to modify the default behavior for loading nodes.
+         * @hidden
+         */
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+        /**
+         * Override this method to modify the default behavior for loading mesh primitive vertex data.
+         * @hidden
+         */
         protected _loadVertexDataAsync(context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Override this method to modify the default behavior for loading materials. */
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading textures. */
+        /**
+         * Override this method to modify the default behavior for loading materials.
+         * @hidden
+         */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Override this method to modify the default behavior for loading textures.
+         * @hidden
+         */
         protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading uris. */
+        /**
+         * Override this method to modify the default behavior for loading uris.
+         * @hidden
+         */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
-        /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
-        /** Helper method called by the loader to allow extensions to override loading scenes. */
+        /**
+         * Helper method called by a loader extension to load an glTF extension.
+         * @hidden
+         */
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading scenes.
+         * @hidden
+         */
+        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 to allow extensions to override loading scenes.
+         * @hidden
+         */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading nodes. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading nodes.
+         * @hidden
+         */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+         * @hidden
+         */
         static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Helper method called by the loader to allow extensions to override loading materials. */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading textures. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading materials.
+         * @hidden
+         */
+        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading textures.
+         * @hidden
+         */
         static _LoadTextureAsync(loader: GLTFLoader, context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading uris. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading uris.
+         * @hidden
+         */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
     }
 }
@@ -1440,7 +1490,7 @@ declare module BABYLON.GLTF2.Extensions {
         constructor(loader: GLTFLoader);
         dispose(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         /**
          * Gets an array of LOD properties from lowest to highest.
@@ -1454,8 +1504,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_minecraftMesh extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1464,8 +1513,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1490,7 +1538,8 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /** @hidden */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1502,7 +1551,7 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
     }
 }

+ 168 - 108
dist/preview release/loaders/babylonjs.loaders.js

@@ -1389,8 +1389,8 @@ var BABYLON;
                 }
             }
             var createLoaders = {
-                1: GLTFFileLoader.CreateGLTFLoaderV1,
-                2: GLTFFileLoader.CreateGLTFLoaderV2
+                1: GLTFFileLoader._CreateGLTFLoaderV1,
+                2: GLTFFileLoader._CreateGLTFLoaderV2
             };
             var createLoader = createLoaders[version.major];
             if (!createLoader) {
@@ -3208,7 +3208,7 @@ var BABYLON;
         }());
         GLTF1.GLTFLoader = GLTFLoader;
         ;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV1 = function () { return new GLTFLoader(); };
     })(GLTF1 = BABYLON.GLTF1 || (BABYLON.GLTF1 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -3789,15 +3789,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFMaterialsCommonExtension.js.map
 
 
+
+
+//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
+
+
+/**
+ * Defines the module used to import/export glTF 2.0 assets
+ */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        /** @hidden */
         var _ArrayItem = /** @class */ (function () {
             function _ArrayItem() {
             }
-            /** @hidden */
             _ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -3807,25 +3813,6 @@ var BABYLON;
             };
             return _ArrayItem;
         }());
-        GLTF2._ArrayItem = _ArrayItem;
-    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
-})(BABYLON || (BABYLON = {}));
-
-//# sourceMappingURL=babylon.glTFLoaderUtilities.js.map
-
-
-
-
-//# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
-
-
-/**
- * Defines the module used to import/export glTF 2.0 assets
- */
-var BABYLON;
-(function (BABYLON) {
-    var GLTF2;
-    (function (GLTF2) {
         /**
          * Loader for loading a glTF 2.0 asset
          */
@@ -4071,19 +4058,19 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._setupData = function () {
-                GLTF2._ArrayItem.Assign(this._gltf.accessors);
-                GLTF2._ArrayItem.Assign(this._gltf.animations);
-                GLTF2._ArrayItem.Assign(this._gltf.buffers);
-                GLTF2._ArrayItem.Assign(this._gltf.bufferViews);
-                GLTF2._ArrayItem.Assign(this._gltf.cameras);
-                GLTF2._ArrayItem.Assign(this._gltf.images);
-                GLTF2._ArrayItem.Assign(this._gltf.materials);
-                GLTF2._ArrayItem.Assign(this._gltf.meshes);
-                GLTF2._ArrayItem.Assign(this._gltf.nodes);
-                GLTF2._ArrayItem.Assign(this._gltf.samplers);
-                GLTF2._ArrayItem.Assign(this._gltf.scenes);
-                GLTF2._ArrayItem.Assign(this._gltf.skins);
-                GLTF2._ArrayItem.Assign(this._gltf.textures);
+                _ArrayItem.Assign(this._gltf.accessors);
+                _ArrayItem.Assign(this._gltf.animations);
+                _ArrayItem.Assign(this._gltf.buffers);
+                _ArrayItem.Assign(this._gltf.bufferViews);
+                _ArrayItem.Assign(this._gltf.cameras);
+                _ArrayItem.Assign(this._gltf.images);
+                _ArrayItem.Assign(this._gltf.materials);
+                _ArrayItem.Assign(this._gltf.meshes);
+                _ArrayItem.Assign(this._gltf.nodes);
+                _ArrayItem.Assign(this._gltf.samplers);
+                _ArrayItem.Assign(this._gltf.scenes);
+                _ArrayItem.Assign(this._gltf.skins);
+                _ArrayItem.Assign(this._gltf.textures);
                 if (this._gltf.nodes) {
                     var nodeParents = {};
                     for (var _i = 0, _a = this._gltf.nodes; _i < _a.length; _i++) {
@@ -4266,7 +4253,7 @@ var BABYLON;
                     throw new Error(context + ": Invalid recursive node hierarchy");
                 }
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent._babylonMesh);
+                var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
                 node._babylonMesh = babylonMesh;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
@@ -4294,7 +4281,7 @@ var BABYLON;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
-                GLTF2._ArrayItem.Assign(primitives);
+                _ArrayItem.Assign(primitives);
                 if (primitives.length === 1) {
                     var primitive = primitives[0];
                     promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
@@ -4334,7 +4321,7 @@ var BABYLON;
                 }
                 else {
                     var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
-                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                    promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
@@ -4525,7 +4512,7 @@ var BABYLON;
                     return babylonBone;
                 }
                 var babylonParentBone = null;
-                if (node._parent._babylonMesh !== this._rootBabylonMesh) {
+                if (node._parent && node._parent._babylonMesh !== this._rootBabylonMesh) {
                     babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
                 var boneIndex = skin.joints.indexOf(node._index);
@@ -4615,8 +4602,8 @@ var BABYLON;
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
-                GLTF2._ArrayItem.Assign(animation.channels);
-                GLTF2._ArrayItem.Assign(animation.samplers);
+                _ArrayItem.Assign(animation.channels);
+                _ArrayItem.Assign(animation.samplers);
                 for (var _i = 0, _a = animation.channels; _i < _a.length; _i++) {
                     var channel = _a[_i];
                     promises.push(this._loadAnimationChannelAsync(context + "/channels/" + channel._index, context, animation, channel, babylonAnimationGroup));
@@ -4970,8 +4957,8 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             /** @hidden */
-            GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
-                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
+            GLTFLoader.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
                     return promise;
                 }
@@ -4979,7 +4966,7 @@ var BABYLON;
                 var babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
                     var promises = new Array();
-                    var name_3 = material.name || "materialSG_" + material._index;
+                    var name_3 = material.name || "material_" + material._index;
                     var babylonMaterial = this._createMaterial(name_3, babylonDrawMode);
                     promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
                     promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
@@ -5372,7 +5359,7 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTF2.GLTFLoader = GLTFLoader;
-        BABYLON.GLTFFileLoader.CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -5387,28 +5374,59 @@ var BABYLON;
          * Abstract class that can be implemented to extend existing glTF loader behavior.
          */
         var GLTFLoaderExtension = /** @class */ (function () {
+            /**
+             * Creates new GLTFLoaderExtension
+             * @param loader defines the GLTFLoader to use
+             */
             function GLTFLoaderExtension(loader) {
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
             // #region Overridable Methods
-            /** Override this method to modify the default behavior for loading scenes. */
+            /**
+             * Override this method to modify the default behavior for loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadSceneAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading nodes. */
+            /**
+             * Override this method to modify the default behavior for loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadNodeAsync = function (context, node) { return null; };
-            /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+            /**
+             * Override this method to modify the default behavior for loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { return null; };
-            /** Override this method to modify the default behavior for loading materials. */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
-            /** Override this method to modify the default behavior for loading textures. */
+            /**
+             * Override this method to modify the default behavior for loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
+            /**
+             * Override this method to modify the default behavior for loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadTextureAsync = function (context, textureInfo, assign) { return null; };
-            /** Override this method to modify the default behavior for loading uris. */
+            /**
+             * Override this method to modify the default behavior for loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             // #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.
+             * @hidden
+             */
             GLTFLoaderExtension.prototype._loadExtensionAsync = function (context, property, actionAsync) {
                 if (!property.extensions) {
                     return null;
@@ -5418,7 +5436,7 @@ var BABYLON;
                 if (!extension) {
                     return null;
                 }
-                // Clear out the extension before executing the action to avoid recursing into the same property.
+                // Clear out the extension before executing the action to avoid infinite recursion.
                 delete extensions[this.name];
                 try {
                     return actionAsync(context + "/extensions/" + this.name, extension);
@@ -5428,27 +5446,68 @@ var BABYLON;
                     extensions[this.name] = extension;
                 }
             };
-            /** 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
+             */
+            GLTFLoaderExtension.prototype._loadExtrasValueAsync = function (context, property, actionAsync) {
+                if (!property.extras) {
+                    return null;
+                }
+                var extras = property.extras;
+                var value = extras[this.name];
+                if (value === undefined) {
+                    return null;
+                }
+                // Clear out the extras value before executing the action to avoid infinite recursion.
+                delete extras[this.name];
+                try {
+                    return actionAsync(context + "/extras/" + this.name, value);
+                }
+                finally {
+                    // Restore the extras value after executing the action.
+                    extras[this.name] = value;
+                }
+            };
+            /**
+             * Helper method called by the loader to allow extensions to override loading scenes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadSceneAsync = function (loader, context, scene) {
                 return loader._applyExtensions(function (extension) { return extension._loadSceneAsync(context, scene); });
             };
-            /** Helper method called by the loader to allow extensions to override loading nodes. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading nodes.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadNodeAsync = function (loader, context, node) {
                 return loader._applyExtensions(function (extension) { return extension._loadNodeAsync(context, node); });
             };
-            /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadVertexDataAsync = function (loader, context, primitive, babylonMesh) {
                 return loader._applyExtensions(function (extension) { return extension._loadVertexDataAsync(context, primitive, babylonMesh); });
             };
-            /** Helper method called by the loader to allow extensions to override loading materials. */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            /**
+             * Helper method called by the loader to allow extensions to override loading materials.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading textures. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading textures.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadTextureAsync = function (loader, context, textureInfo, assign) {
                 return loader._applyExtensions(function (extension) { return extension._loadTextureAsync(context, textureInfo, assign); });
             };
-            /** Helper method called by the loader to allow extensions to override loading uris. */
+            /**
+             * Helper method called by the loader to allow extensions to override loading uris.
+             * @hidden
+             */
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
@@ -5573,7 +5632,7 @@ var BABYLON;
                         return firstPromise;
                     });
                 };
-                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     // Don't load material LODs if already loading a node LOD.
                     if (this._loadingNodeLOD) {
@@ -5590,7 +5649,7 @@ var BABYLON;
                                     _this._loadMaterialSignals[materialLOD._index] = new BABYLON.Deferred();
                                 }
                             }
-                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
+                            var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, mesh, babylonMesh, babylonDrawMode, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     var babylonDataLOD = materialLOD._babylonData;
                                     assign(babylonDataLOD[babylonDrawMode].material);
@@ -5680,29 +5739,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_minecraftMesh = /** @class */ (function (_super) {
                 __extends(MSFT_minecraftMesh, _super);
-                function MSFT_minecraftMesh(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_minecraftMesh() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (material.needAlphaBlending()) {
-                            material.forceDepthWrite = true;
-                            material.separateCullingPass = true;
-                        }
-                        material.backFaceCulling = material.forceDepthWrite;
-                        material.twoSidedLighting = true;
-                    };
-                    var meshes = loader._gltf.meshes;
-                    if (meshes && meshes.length) {
-                        for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
-                            var mesh = meshes_1[_i];
-                            if (mesh && mesh.extras && mesh.extras.MSFT_minecraftMesh) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_minecraftMesh.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, mesh, function (extensionContext, value) {
+                        if (value) {
+                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
+                                if (babylonMaterial.needAlphaBlending()) {
+                                    babylonMaterial.forceDepthWrite = true;
+                                    babylonMaterial.separateCullingPass = true;
+                                }
+                                babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite;
+                                babylonMaterial.twoSidedLighting = true;
+                                assign(babylonMaterial);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_minecraftMesh;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_minecraftMesh = MSFT_minecraftMesh;
@@ -5725,29 +5783,28 @@ var BABYLON;
             /** @hidden */
             var MSFT_sRGBFactors = /** @class */ (function (_super) {
                 __extends(MSFT_sRGBFactors, _super);
-                function MSFT_sRGBFactors(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_sRGBFactors() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
-                    _this._onMaterialLoaded = function (material) {
-                        if (!material.albedoTexture) {
-                            material.albedoColor.toLinearSpaceToRef(material.albedoColor);
-                        }
-                        if (!material.reflectivityTexture) {
-                            material.reflectivityColor.toLinearSpaceToRef(material.reflectivityColor);
-                        }
-                    };
-                    var materials = loader._gltf.materials;
-                    if (materials && materials.length) {
-                        for (var _i = 0, materials_1 = materials; _i < materials_1.length; _i++) {
-                            var material = materials_1[_i];
-                            if (material && material.extras && material.extras.MSFT_sRGBFactors) {
-                                _this._loader.onMaterialLoadedObservable.add(_this._onMaterialLoaded);
-                                break;
-                            }
-                        }
-                    }
                     return _this;
                 }
+                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtrasValueAsync(context, material, function (extensionContext, 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);
+                            });
+                        }
+                        return null;
+                    });
+                };
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -5868,7 +5925,8 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                /** @hidden */
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
@@ -5947,7 +6005,7 @@ var BABYLON;
                     _this.name = NAME;
                     return _this;
                 }
-                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function () {
                         material._babylonData = material._babylonData || {};
@@ -6005,6 +6063,8 @@ var BABYLON;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
+//# sourceMappingURL=KHR_materials_unlit.js.map
+
 
 
 var BABYLON;

File diff suppressed because it is too large
+ 4 - 4
dist/preview release/loaders/babylonjs.loaders.min.js


+ 87 - 38
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -267,12 +267,14 @@ declare module BABYLON {
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         /**
          * Factory function that creates a glTF 1.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV1: () => IGLTFLoader;
+        static _CreateGLTFLoaderV1: () => IGLTFLoader;
         /**
          * Factory function that creates a glTF 2.0 loader
+         * @hidden
          */
-        static CreateGLTFLoaderV2: () => IGLTFLoader;
+        static _CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed
          */
@@ -1050,22 +1052,13 @@ declare module BABYLON.GLTF1 {
 }
 
 
+
 declare module BABYLON.GLTF2 {
     /** @hidden */
     interface _IArrayItem {
         _index: number;
     }
     /** @hidden */
-    class _ArrayItem {
-        /** @hidden */
-        static Assign(values?: _IArrayItem[]): void;
-    }
-}
-
-
-
-declare module BABYLON.GLTF2 {
-    /** @hidden */
     interface _ILoaderAccessor extends IAccessor, _IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
@@ -1081,7 +1074,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderAnimationSampler extends IAnimationSampler, _IArrayItem {
-        _data: Promise<_ILoaderAnimationSamplerData>;
+        _data?: Promise<_ILoaderAnimationSamplerData>;
     }
     /** @hidden */
     interface _ILoaderAnimation extends IAnimation, _IArrayItem {
@@ -1124,7 +1117,7 @@ declare module BABYLON.GLTF2 {
     }
     /** @hidden */
     interface _ILoaderNode extends INode, _IArrayItem {
-        _parent: _ILoaderNode;
+        _parent?: _ILoaderNode;
         _babylonMesh?: Mesh;
         _primitiveBabylonMeshes?: Mesh[];
         _babylonBones?: Bone[];
@@ -1340,7 +1333,7 @@ declare module BABYLON.GLTF2 {
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         /** @hidden */
-        _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
         /** @hidden */
         _createMaterial(name: string, drawMode: number): PBRMaterial;
         /** @hidden */
@@ -1376,36 +1369,93 @@ declare module BABYLON.GLTF2 {
      * Abstract class that can be implemented to extend existing glTF loader behavior.
      */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
+        /**
+         * Creates new GLTFLoaderExtension
+         * @param loader defines the GLTFLoader to use
+         */
         constructor(loader: GLTFLoader);
+        /**
+         * Release all resources
+         */
         dispose(): void;
-        /** Override this method to modify the default behavior for loading scenes. */
+        /**
+         * Override this method to modify the default behavior for loading scenes.
+         * @hidden
+         */
         protected _loadSceneAsync(context: string, node: _ILoaderScene): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading nodes. */
+        /**
+         * Override this method to modify the default behavior for loading nodes.
+         * @hidden
+         */
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
+        /**
+         * Override this method to modify the default behavior for loading mesh primitive vertex data.
+         * @hidden
+         */
         protected _loadVertexDataAsync(context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Override this method to modify the default behavior for loading materials. */
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading textures. */
+        /**
+         * Override this method to modify the default behavior for loading materials.
+         * @hidden
+         */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Override this method to modify the default behavior for loading textures.
+         * @hidden
+         */
         protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Override this method to modify the default behavior for loading uris. */
+        /**
+         * Override this method to modify the default behavior for loading uris.
+         * @hidden
+         */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
-        /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
-        /** Helper method called by the loader to allow extensions to override loading scenes. */
+        /**
+         * Helper method called by a loader extension to load an glTF extension.
+         * @hidden
+         */
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading scenes.
+         * @hidden
+         */
+        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 to allow extensions to override loading scenes.
+         * @hidden
+         */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading nodes. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading nodes.
+         * @hidden
+         */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading mesh primitive vertex data.
+         * @hidden
+         */
         static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-        /** Helper method called by the loader to allow extensions to override loading materials. */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading textures. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading materials.
+         * @hidden
+         */
+        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading textures.
+         * @hidden
+         */
         static _LoadTextureAsync(loader: GLTFLoader, context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>>;
-        /** Helper method called by the loader to allow extensions to override loading uris. */
+        /**
+         * Helper method called by the loader to allow extensions to override loading uris.
+         * @hidden
+         */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
     }
 }
@@ -1447,7 +1497,7 @@ declare module BABYLON.GLTF2.Extensions {
         constructor(loader: GLTFLoader);
         dispose(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         /**
          * Gets an array of LOD properties from lowest to highest.
@@ -1461,8 +1511,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_minecraftMesh extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1471,8 +1520,7 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
-        constructor(loader: GLTFLoader);
-        private _onMaterialLoaded;
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
     }
 }
 
@@ -1497,7 +1545,8 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        /** @hidden */
+        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1509,7 +1558,7 @@ declare module BABYLON.GLTF2.Extensions {
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, 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>>;
         private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
     }
 }

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

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

+ 1 - 1
dist/preview release/materialsLibrary/babylon.mixMaterial.js

@@ -227,7 +227,7 @@ var BABYLON;
                         }
                     }
                 }
-                if (this.mixTexture2) {
+                if (this._mixTexture2) {
                     this._activeEffect.setTexture("mixMap2Sampler", this._mixTexture2);
                     if (BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                         if (this._diffuseTexture5) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.mixMaterial.min.js


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

@@ -3463,7 +3463,7 @@ var BABYLON;
                         }
                     }
                 }
-                if (this.mixTexture2) {
+                if (this._mixTexture2) {
                     this._activeEffect.setTexture("mixMap2Sampler", this._mixTexture2);
                     if (BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                         if (this._diffuseTexture5) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js


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

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

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

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

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

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

+ 14 - 5
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -78,6 +78,7 @@ declare module BABYLON.GLTF2 {
          * Stores all the generated material information, which represents the appearance of each primitive
          */
         private materials;
+        private materialMap;
         /**
          * Stores all the generated texture information, which is referenced by glTF materials
          */
@@ -421,7 +422,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData mapping of texture names to base64 textures
          * @param hasTextureCoords specifies if texture coordinates are present on the material
          */
-        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -469,7 +472,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -492,7 +497,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -589,13 +596,15 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
             };
         }, hasTextureCoords: boolean): Promise<void>;
-        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
         private static GetPixelsFromTexture(babylonTexture);
         /**
          * Extracts a texture from a Babylon texture into file data and glTF data

+ 64 - 47
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -79,6 +79,7 @@ var BABYLON;
                 this.nodes = [];
                 this.images = [];
                 this.materials = [];
+                this.materialMap = [];
                 this.textures = [];
                 this.samplers = [];
                 this.animations = [];
@@ -860,11 +861,11 @@ var BABYLON;
                                 else if (babylonMaterial instanceof BABYLON.MultiMaterial) {
                                     babylonMaterial = babylonMaterial.subMaterials[submesh.materialIndex];
                                     if (babylonMaterial) {
-                                        materialIndex = this.babylonScene.materials.indexOf(babylonMaterial);
+                                        materialIndex = this.materialMap[babylonMaterial.uniqueId];
                                     }
                                 }
                                 else {
-                                    materialIndex = this.babylonScene.materials.indexOf(babylonMaterial);
+                                    materialIndex = this.materialMap[babylonMaterial.uniqueId];
                                 }
                             }
                             var glTFMaterial = materialIndex != null ? this.materials[materialIndex] : null;
@@ -905,43 +906,41 @@ var BABYLON;
                                 this.accessors.push(accessor);
                                 meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            if (babylonMaterial) {
-                                if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
-                                    var sideOrientation = this.babylonScene.materials[materialIndex].sideOrientation;
-                                    if (this.convertToRightHandedSystem && sideOrientation === BABYLON.Material.ClockWiseSideOrientation) {
-                                        //Overwrite the indices to be counter-clockwise
-                                        var byteOffset = indexBufferViewIndex != null ? this.bufferViews[indexBufferViewIndex].byteOffset : null;
-                                        if (byteOffset == null) {
-                                            byteOffset = 0;
-                                        }
-                                        var babylonIndices = null;
-                                        if (indexBufferViewIndex != null) {
-                                            babylonIndices = bufferMesh.getIndices();
-                                        }
-                                        if (babylonIndices) {
-                                            this.reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
-                                        }
-                                        else {
-                                            for (var _d = 0, attributeData_3 = attributeData; _d < attributeData_3.length; _d++) {
-                                                var attribute = attributeData_3[_d];
-                                                var vertexData = bufferMesh.getVerticesData(attribute.kind);
-                                                if (vertexData) {
-                                                    var byteOffset_1 = this.bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
-                                                    if (!byteOffset_1) {
-                                                        byteOffset_1 = 0;
-                                                    }
-                                                    this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
+                            if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
+                                var sideOrientation = this.babylonScene.materials[materialIndex].sideOrientation;
+                                if (this.convertToRightHandedSystem && sideOrientation === BABYLON.Material.ClockWiseSideOrientation) {
+                                    //Overwrite the indices to be counter-clockwise
+                                    var byteOffset = indexBufferViewIndex != null ? this.bufferViews[indexBufferViewIndex].byteOffset : null;
+                                    if (byteOffset == null) {
+                                        byteOffset = 0;
+                                    }
+                                    var babylonIndices = null;
+                                    if (indexBufferViewIndex != null) {
+                                        babylonIndices = bufferMesh.getIndices();
+                                    }
+                                    if (babylonIndices) {
+                                        this.reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
+                                    }
+                                    else {
+                                        for (var _d = 0, attributeData_3 = attributeData; _d < attributeData_3.length; _d++) {
+                                            var attribute = attributeData_3[_d];
+                                            var vertexData = bufferMesh.getVerticesData(attribute.kind);
+                                            if (vertexData) {
+                                                var byteOffset_1 = this.bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
+                                                if (!byteOffset_1) {
+                                                    byteOffset_1 = 0;
                                                 }
+                                                this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
                                             }
                                         }
                                     }
-                                    if (!uvCoordsPresent && GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
-                                        var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
-                                        this.materials.push(newMat);
-                                        materialIndex = this.materials.length - 1;
-                                    }
-                                    meshPrimitive.material = materialIndex;
                                 }
+                                if (!uvCoordsPresent && GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
+                                    var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
+                                    this.materials.push(newMat);
+                                    materialIndex = this.materials.length - 1;
+                                }
+                                meshPrimitive.material = materialIndex;
                             }
                             mesh.primitives.push(meshPrimitive);
                         }
@@ -961,7 +960,7 @@ var BABYLON;
                 var glTFNode;
                 var directDescendents;
                 var nodes = babylonScene.transformNodes.concat(babylonScene.meshes);
-                return GLTF2._GLTFMaterial._ConvertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.samplers, this.materials, this.imageData, true).then(function () {
+                return GLTF2._GLTFMaterial._ConvertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.samplers, this.materials, this.materialMap, this.imageData, true).then(function () {
                     _this.nodeMap = _this.createNodeMapAndAnimations(babylonScene, nodes, _this.shouldExportTransformNode, binaryWriter);
                     _this.totalByteLength = binaryWriter.getByteOffset();
                     // Build Hierarchy with the node map.
@@ -1342,18 +1341,18 @@ var BABYLON;
              * @param imageData mapping of texture names to base64 textures
              * @param hasTextureCoords specifies if texture coordinates are present on the material
              */
-            _GLTFMaterial._ConvertMaterialsToGLTFAsync = function (babylonMaterials, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertMaterialsToGLTFAsync = function (babylonMaterials, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 for (var _i = 0, babylonMaterials_1 = babylonMaterials; _i < babylonMaterials_1.length; _i++) {
                     var babylonMaterial = babylonMaterials_1[_i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                        promises.push(_GLTFMaterial._ConvertStandardMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertStandardMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                        promises.push(_GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                        promises.push(_GLTFMaterial._ConvertPBRMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertPBRMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else {
                         BABYLON.Tools.Warn("Unsupported material type: " + babylonMaterial.name);
@@ -1547,7 +1546,7 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertStandardMaterialAsync = function (babylonStandardMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertStandardMaterialAsync = function (babylonStandardMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var alphaMode = this._GetAlphaMode(babylonStandardMaterial);
                 var useAlpha = alphaMode !== "OPAQUE" /* OPAQUE */ ? true : false;
                 var promises = [];
@@ -1613,7 +1612,24 @@ var BABYLON;
                     glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                    switch (alphaMode) {
+                        case "BLEND" /* BLEND */: {
+                            glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                            break;
+                        }
+                        case "MASK" /* MASK */: {
+                            glTFMaterial.alphaMode = "MASK" /* MASK */;
+                            glTFMaterial.alphaCutoff = babylonStandardMaterial.alphaCutOff;
+                            break;
+                        }
+                        default: {
+                            BABYLON.Tools.Warn("Unsupported alpha mode " + alphaMode);
+                        }
+                    }
+                }
                 materials.push(glTFMaterial);
+                materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1;
                 return Promise.all(promises).then(function () { });
             };
             /**
@@ -1655,7 +1671,7 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
@@ -1739,6 +1755,7 @@ var BABYLON;
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                 materials.push(glTFMaterial);
+                materialMap[babylonPBRMetalRoughMaterial.uniqueId] = materials.length - 1;
                 return Promise.all(promises).then(function () { });
             };
             /**
@@ -2166,9 +2183,8 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertPBRMaterialAsync = function (babylonPBRMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMaterialAsync = function (babylonPBRMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
-                //  let metallicRoughness: Nullable<_IPBRMetallicRoughness>;
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                 };
@@ -2183,15 +2199,15 @@ var BABYLON;
                         ];
                     }
                     return this._ConvertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, images, textures, samplers, glTFPbrMetallicRoughness, imageData, hasTextureCoords).then(function (metallicRoughness) {
-                        return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+                        return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
                     });
                 }
                 else {
                     var metallicRoughness = this._ConvertSpecGlossFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, samplers, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
-                    return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+                    return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
                 }
             };
-            _GLTFMaterial.SetMetallicRoughnessPbrMaterial = function (metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial.SetMetallicRoughnessPbrMaterial = function (metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 if (metallicRoughness) {
                     var alphaMode = null;
@@ -2268,6 +2284,7 @@ var BABYLON;
                     }
                     glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                     materials.push(glTFMaterial);
+                    materialMap[babylonPBRMaterial.uniqueId] = materials.length - 1;
                 }
                 return Promise.all(promises).then(function (result) { });
             };
@@ -2305,7 +2322,7 @@ var BABYLON;
                 else {
                     samplerIndex = foundSamplerIndex;
                 }
-                var textureName = "texture_" + (textures.length - 1).toString();
+                var textureName = BABYLON.Tools.RandomId();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
                     textureName = textureData.url || textureName;

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 14 - 5
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -86,6 +86,7 @@ declare module BABYLON.GLTF2 {
          * Stores all the generated material information, which represents the appearance of each primitive
          */
         private materials;
+        private materialMap;
         /**
          * Stores all the generated texture information, which is referenced by glTF materials
          */
@@ -429,7 +430,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData mapping of texture names to base64 textures
          * @param hasTextureCoords specifies if texture coordinates are present on the material
          */
-        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -477,7 +480,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -500,7 +505,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -597,13 +604,15 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
             };
         }, hasTextureCoords: boolean): Promise<void>;
-        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
         private static GetPixelsFromTexture(babylonTexture);
         /**
          * Extracts a texture from a Babylon texture into file data and glTF data

+ 64 - 47
dist/preview release/serializers/babylonjs.serializers.js

@@ -229,6 +229,7 @@ var BABYLON;
                 this.nodes = [];
                 this.images = [];
                 this.materials = [];
+                this.materialMap = [];
                 this.textures = [];
                 this.samplers = [];
                 this.animations = [];
@@ -1010,11 +1011,11 @@ var BABYLON;
                                 else if (babylonMaterial instanceof BABYLON.MultiMaterial) {
                                     babylonMaterial = babylonMaterial.subMaterials[submesh.materialIndex];
                                     if (babylonMaterial) {
-                                        materialIndex = this.babylonScene.materials.indexOf(babylonMaterial);
+                                        materialIndex = this.materialMap[babylonMaterial.uniqueId];
                                     }
                                 }
                                 else {
-                                    materialIndex = this.babylonScene.materials.indexOf(babylonMaterial);
+                                    materialIndex = this.materialMap[babylonMaterial.uniqueId];
                                 }
                             }
                             var glTFMaterial = materialIndex != null ? this.materials[materialIndex] : null;
@@ -1055,43 +1056,41 @@ var BABYLON;
                                 this.accessors.push(accessor);
                                 meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            if (babylonMaterial) {
-                                if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
-                                    var sideOrientation = this.babylonScene.materials[materialIndex].sideOrientation;
-                                    if (this.convertToRightHandedSystem && sideOrientation === BABYLON.Material.ClockWiseSideOrientation) {
-                                        //Overwrite the indices to be counter-clockwise
-                                        var byteOffset = indexBufferViewIndex != null ? this.bufferViews[indexBufferViewIndex].byteOffset : null;
-                                        if (byteOffset == null) {
-                                            byteOffset = 0;
-                                        }
-                                        var babylonIndices = null;
-                                        if (indexBufferViewIndex != null) {
-                                            babylonIndices = bufferMesh.getIndices();
-                                        }
-                                        if (babylonIndices) {
-                                            this.reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
-                                        }
-                                        else {
-                                            for (var _d = 0, attributeData_3 = attributeData; _d < attributeData_3.length; _d++) {
-                                                var attribute = attributeData_3[_d];
-                                                var vertexData = bufferMesh.getVerticesData(attribute.kind);
-                                                if (vertexData) {
-                                                    var byteOffset_1 = this.bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
-                                                    if (!byteOffset_1) {
-                                                        byteOffset_1 = 0;
-                                                    }
-                                                    this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
+                            if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
+                                var sideOrientation = this.babylonScene.materials[materialIndex].sideOrientation;
+                                if (this.convertToRightHandedSystem && sideOrientation === BABYLON.Material.ClockWiseSideOrientation) {
+                                    //Overwrite the indices to be counter-clockwise
+                                    var byteOffset = indexBufferViewIndex != null ? this.bufferViews[indexBufferViewIndex].byteOffset : null;
+                                    if (byteOffset == null) {
+                                        byteOffset = 0;
+                                    }
+                                    var babylonIndices = null;
+                                    if (indexBufferViewIndex != null) {
+                                        babylonIndices = bufferMesh.getIndices();
+                                    }
+                                    if (babylonIndices) {
+                                        this.reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
+                                    }
+                                    else {
+                                        for (var _d = 0, attributeData_3 = attributeData; _d < attributeData_3.length; _d++) {
+                                            var attribute = attributeData_3[_d];
+                                            var vertexData = bufferMesh.getVerticesData(attribute.kind);
+                                            if (vertexData) {
+                                                var byteOffset_1 = this.bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
+                                                if (!byteOffset_1) {
+                                                    byteOffset_1 = 0;
                                                 }
+                                                this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
                                             }
                                         }
                                     }
-                                    if (!uvCoordsPresent && GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
-                                        var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
-                                        this.materials.push(newMat);
-                                        materialIndex = this.materials.length - 1;
-                                    }
-                                    meshPrimitive.material = materialIndex;
                                 }
+                                if (!uvCoordsPresent && GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
+                                    var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
+                                    this.materials.push(newMat);
+                                    materialIndex = this.materials.length - 1;
+                                }
+                                meshPrimitive.material = materialIndex;
                             }
                             mesh.primitives.push(meshPrimitive);
                         }
@@ -1111,7 +1110,7 @@ var BABYLON;
                 var glTFNode;
                 var directDescendents;
                 var nodes = babylonScene.transformNodes.concat(babylonScene.meshes);
-                return GLTF2._GLTFMaterial._ConvertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.samplers, this.materials, this.imageData, true).then(function () {
+                return GLTF2._GLTFMaterial._ConvertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.samplers, this.materials, this.materialMap, this.imageData, true).then(function () {
                     _this.nodeMap = _this.createNodeMapAndAnimations(babylonScene, nodes, _this.shouldExportTransformNode, binaryWriter);
                     _this.totalByteLength = binaryWriter.getByteOffset();
                     // Build Hierarchy with the node map.
@@ -1492,18 +1491,18 @@ var BABYLON;
              * @param imageData mapping of texture names to base64 textures
              * @param hasTextureCoords specifies if texture coordinates are present on the material
              */
-            _GLTFMaterial._ConvertMaterialsToGLTFAsync = function (babylonMaterials, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertMaterialsToGLTFAsync = function (babylonMaterials, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 for (var _i = 0, babylonMaterials_1 = babylonMaterials; _i < babylonMaterials_1.length; _i++) {
                     var babylonMaterial = babylonMaterials_1[_i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                        promises.push(_GLTFMaterial._ConvertStandardMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertStandardMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                        promises.push(_GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                        promises.push(_GLTFMaterial._ConvertPBRMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords));
+                        promises.push(_GLTFMaterial._ConvertPBRMaterialAsync(babylonMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords));
                     }
                     else {
                         BABYLON.Tools.Warn("Unsupported material type: " + babylonMaterial.name);
@@ -1697,7 +1696,7 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertStandardMaterialAsync = function (babylonStandardMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertStandardMaterialAsync = function (babylonStandardMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var alphaMode = this._GetAlphaMode(babylonStandardMaterial);
                 var useAlpha = alphaMode !== "OPAQUE" /* OPAQUE */ ? true : false;
                 var promises = [];
@@ -1763,7 +1762,24 @@ var BABYLON;
                     glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                    switch (alphaMode) {
+                        case "BLEND" /* BLEND */: {
+                            glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                            break;
+                        }
+                        case "MASK" /* MASK */: {
+                            glTFMaterial.alphaMode = "MASK" /* MASK */;
+                            glTFMaterial.alphaCutoff = babylonStandardMaterial.alphaCutOff;
+                            break;
+                        }
+                        default: {
+                            BABYLON.Tools.Warn("Unsupported alpha mode " + alphaMode);
+                        }
+                    }
+                }
                 materials.push(glTFMaterial);
+                materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1;
                 return Promise.all(promises).then(function () { });
             };
             /**
@@ -1805,7 +1821,7 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterialAsync = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
@@ -1889,6 +1905,7 @@ var BABYLON;
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                 materials.push(glTFMaterial);
+                materialMap[babylonPBRMetalRoughMaterial.uniqueId] = materials.length - 1;
                 return Promise.all(promises).then(function () { });
             };
             /**
@@ -2316,9 +2333,8 @@ var BABYLON;
              * @param imageData map of image file name to data
              * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
              */
-            _GLTFMaterial._ConvertPBRMaterialAsync = function (babylonPBRMaterial, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMaterialAsync = function (babylonPBRMaterial, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
-                //  let metallicRoughness: Nullable<_IPBRMetallicRoughness>;
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                 };
@@ -2333,15 +2349,15 @@ var BABYLON;
                         ];
                     }
                     return this._ConvertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, images, textures, samplers, glTFPbrMetallicRoughness, imageData, hasTextureCoords).then(function (metallicRoughness) {
-                        return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+                        return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
                     });
                 }
                 else {
                     var metallicRoughness = this._ConvertSpecGlossFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, samplers, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
-                    return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+                    return _GLTFMaterial.SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
                 }
             };
-            _GLTFMaterial.SetMetallicRoughnessPbrMaterial = function (metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial.SetMetallicRoughnessPbrMaterial = function (metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords) {
                 var promises = [];
                 if (metallicRoughness) {
                     var alphaMode = null;
@@ -2418,6 +2434,7 @@ var BABYLON;
                     }
                     glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                     materials.push(glTFMaterial);
+                    materialMap[babylonPBRMaterial.uniqueId] = materials.length - 1;
                 }
                 return Promise.all(promises).then(function (result) { });
             };
@@ -2455,7 +2472,7 @@ var BABYLON;
                 else {
                     samplerIndex = foundSamplerIndex;
                 }
-                var textureName = "texture_" + (textures.length - 1).toString();
+                var textureName = BABYLON.Tools.RandomId();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
                     textureName = textureData.url || textureName;

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/serializers/babylonjs.serializers.min.js


+ 14 - 5
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -93,6 +93,7 @@ declare module BABYLON.GLTF2 {
          * Stores all the generated material information, which represents the appearance of each primitive
          */
         private materials;
+        private materialMap;
         /**
          * Stores all the generated texture information, which is referenced by glTF materials
          */
@@ -436,7 +437,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData mapping of texture names to base64 textures
          * @param hasTextureCoords specifies if texture coordinates are present on the material
          */
-        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertMaterialsToGLTFAsync(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -484,7 +487,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -507,7 +512,9 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMetallicRoughnessMaterialAsync(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -604,13 +611,15 @@ declare module BABYLON.GLTF2 {
          * @param imageData map of image file name to data
          * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
          */
-        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMaterialAsync(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], samplers: ISampler[], materials: IMaterial[], materialMap: {
+            [materialID: number]: number;
+        }, imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
             };
         }, hasTextureCoords: boolean): Promise<void>;
-        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, imageData, hasTextureCoords);
+        private static SetMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, images, textures, samplers, materials, materialMap, imageData, hasTextureCoords);
         private static GetPixelsFromTexture(babylonTexture);
         /**
          * Extracts a texture from a Babylon texture into file data and glTF data

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

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

File diff suppressed because it is too large
+ 1 - 24135
dist/preview release/typedocValidationBaseline.json


File diff suppressed because it is too large
+ 47 - 46
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 644 - 179
dist/preview release/viewer/babylon.viewer.max.js


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

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

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

@@ -22,7 +22,8 @@
 - UtilityLayer class to render another scene as a layer on top of an existing scene ([TrevorDev](https://github.com/TrevorDev))
 - AnimationGroup has now onAnimationGroupEnd observable ([RaananW](https://github.com/RaananW))
 - Pointer drag behavior to enable drag and drop with mouse or 6dof controller on a mesh ([TrevorDev](https://github.com/TrevorDev))
-- Gizmo class used to manipulate meshes in a scene, position gizmo ([TrevorDev](https://github.com/TrevorDev))
+- Gizmo and gizmoManager class used to manipulate meshes in a scene, position, rotation, scale gizmos ([TrevorDev](https://github.com/TrevorDev))
+- Added a new `mesh.ignoreNonUniformScaling` to turn off non uniform scaling compensation ([Deltakosh](https://github.com/deltakosh))
 
 ### glTF Loader
 
@@ -39,8 +40,13 @@
 - Support for model drag and drop onto the canvas ([RaananW](https://github.com/RaananW))
 - New lab feature - global light rotation [#4347](https://github.com/BabylonJS/Babylon.js/issues/4347) ([RaananW](https://github.com/RaananW))
 
+### Documentation
+
+- Added all code comments for GUI
+
 ## Bug fixes
 - VR experience helper will now fire pointer events even when no mesh is currently hit ([TrevorDev](https://github.com/TrevorDev))
+- RawTexture.CreateAlphaTexture no longer fails to create a usable texture ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 
@@ -48,7 +54,9 @@
 - Physics `unregisterOnPhysicsCollide` didn't remove callback correctly [#4291](https://github.com/BabylonJS/Babylon.js/issues/4291) ([RaananW](https://github.com/RaananW))
 - Added missing getter and setter for global exposure in ColorCurves ([RaananW](https://github.com/RaananW))
 - Fixed an issue with view matrix when `ArcRotateCamera` was used with collisions ([Deltakosh](https://github.com/deltakosh))
-- Fixed a bug with setting `unlit` on `PBRMaterial` after the material is ready ([bghgary](http://www.github.com/bghgary))
+- Fixed a bug with setting `unlit` on `PBRMaterial` after the material is ready (Wrong dirty flags) ([bghgary](http://www.github.com/bghgary))
+- Fixed `HighlightLayer` support on browsers not supporting HalfFloat ([sebavan](http://www.github.com/sebavan))
+- Fixed support for R and RG texture formats ([sebavan](http://www.github.com/sebavan))
 
 ### Viewer
 
@@ -60,3 +68,4 @@
 - It wasn't possible to disable camera behavior(s) using configuration  [#4348](https://github.com/BabylonJS/Babylon.js/issues/4348) ([RaananW](https://github.com/RaananW))
 
 ## Breaking changes
+- Fixing support for R and RG texture formats made us remove TextureFormat_R32F and TextureFormat_RG32F as they were mixing formats and types. Please, use the respective TextureFormat_R and TextureFormat_RG with the Float types ([sebavan](http://www.github.com/sebavan))

+ 134 - 10
gui/src/2D/advancedDynamicTexture.ts

@@ -1,12 +1,33 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
+/**
+ * This module hosts all controls for 2D and 3D GUIs
+ * @see http://doc.babylonjs.com/how_to/gui
+ */
 module BABYLON.GUI {
+    /**
+     * Interface used to define a control that can receive focus
+     */
     export interface IFocusableControl {
+        /**
+         * Function called when the control receives the focus
+         */
         onFocus(): void;
+        /**
+         * Function called when the control loses the focus
+         */
         onBlur(): void;
+        /**
+         * Function called to let the control handle keyboard events
+         * @param evt defines the current keyboard event
+         */
         processKeyboard(evt: KeyboardEvent): void;
     }
 
+    /**
+     * Class used to create texture to support 2D GUI elements
+     * @see http://doc.babylonjs.com/how_to/gui
+     */
     export class AdvancedDynamicTexture extends DynamicTexture {
         private _isDirty = false;
         private _renderObserver: Nullable<Observer<Camera>>;
@@ -16,13 +37,21 @@ module BABYLON.GUI {
         private _pointerObserver: Nullable<Observer<PointerInfo>>;
         private _canvasPointerOutObserver: Nullable<Observer<PointerEvent>>;
         private _background: string;
+        /** @hidden */
         public _rootContainer = new Container("root");
+        /** @hidden */
         public _lastPickedControl: Control;
+        /** @hidden */
         public _lastControlOver: {[pointerId:number]:Control} = {};
+        /** @hidden */
         public _lastControlDown: {[pointerId:number]:Control} = {};
+        /** @hidden */
         public _capturingControl: {[pointerId:number]:Control} = {};
+        /** @hidden */
         public _shouldBlockPointer: boolean;
+        /** @hidden */
         public _layerToDispose: Nullable<Layer>;
+        /** @hidden */
         public _linkedControls = new Array<Control>();
         private _isFullscreen = false;
         private _fullscreenViewport = new Viewport(0, 0, 1, 1);
@@ -39,6 +68,10 @@ module BABYLON.GUI {
          */
         public premulAlpha = false;
 
+        /**
+         * Gets or sets a number used to scale rendering size (2 means that the texture will be twice bigger).
+         * Useful when you want more antialiasing
+         */
         public get renderScale(): number {
             return this._renderScale;
         }
@@ -53,6 +86,7 @@ module BABYLON.GUI {
             this._onResize();
         }
 
+        /** Gets or sets the background color */
         public get background(): string {
             return this._background;
         }
@@ -66,6 +100,11 @@ module BABYLON.GUI {
             this.markAsDirty();
         }
 
+        /**
+         * Gets or sets the ideal width used to design controls.
+         * The GUI will then rescale everything accordingly
+         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         */
         public get idealWidth(): number {
             return this._idealWidth;
         }
@@ -80,6 +119,11 @@ module BABYLON.GUI {
             this._rootContainer._markAllAsDirty();
         }
 
+        /**
+         * Gets or sets the ideal height used to design controls.
+         * The GUI will then rescale everything accordingly
+         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         */        
         public get idealHeight(): number {
             return this._idealHeight;
         }
@@ -94,6 +138,10 @@ module BABYLON.GUI {
             this._rootContainer._markAllAsDirty();
         }
 
+        /**
+         * Gets or sets a boolean indicating if the smallest ideal value must be used if idealWidth and idealHeight are both set
+         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         */
         public get useSmallestIdeal(): boolean {
             return this._useSmallestIdeal;
         }
@@ -108,6 +156,10 @@ module BABYLON.GUI {
             this._rootContainer._markAllAsDirty();
         }
 
+        /**
+         * Gets or sets a boolean indicating if adaptive scaling must be used
+         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         */
         public get renderAtIdealSize(): boolean {
             return this._renderAtIdealSize;
         }
@@ -121,14 +173,23 @@ module BABYLON.GUI {
             this._onResize();
         }
 
+        /**
+         * Gets the underlying layer used to render the texture when in fullscreen mode
+         */
         public get layer(): Nullable<Layer> {
             return this._layerToDispose;
         }
 
+        /**
+         * Gets the root container control
+         */
         public get rootContainer(): Container {
             return this._rootContainer;
         }
 
+        /**
+         * Gets or sets the current focused control
+         */
         public get focusedControl(): Nullable<IFocusableControl> {
             return this._focusedControl;
         }
@@ -149,6 +210,9 @@ module BABYLON.GUI {
             this._focusedControl = control;
         }
 
+        /**
+         * Gets or sets a boolean indicating if the texture must be rendered in background or foreground when in fullscreen mode
+         */
         public get isForeground(): boolean {
             if (!this.layer) {
                 return true;
@@ -166,6 +230,15 @@ module BABYLON.GUI {
             this.layer.isBackground = !value;
         }
 
+        /**
+         * Creates a new AdvancedDynamicTexture
+         * @param name defines the name of the texture
+         * @param width defines the width of the texture
+         * @param height defines the height of the texture
+         * @param scene defines the hosting scene
+         * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
+         * @param samplingMode defines the texture sampling mode (BABYLON.Texture.NEAREST_SAMPLINGMODE by default)
+         */
         constructor(name: string, width = 0, height = 0, scene: Nullable<Scene>, generateMipMaps = false, samplingMode = Texture.NEAREST_SAMPLINGMODE) {
             super(name, { width: width, height: height }, scene, generateMipMaps, samplingMode, Engine.TEXTUREFORMAT_RGBA);
 
@@ -200,6 +273,11 @@ module BABYLON.GUI {
             this._texture.isReady = true;
         }
 
+        /**
+         * Function used to execute a function on all controls
+         * @param func defines the function to execute
+         * @param container defines the container where controls belong. If null the root container will be used
+         */
         public executeOnAllControls(func: (control: Control) => void, container?: Container) {
             if (!container) {
                 container = this._rootContainer;
@@ -214,6 +292,9 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Marks the texture as dirty forcing a complete update
+         */
         public markAsDirty() {
             this._isDirty = true;
 
@@ -226,22 +307,37 @@ module BABYLON.GUI {
 
         /**
          * Helper function used to create a new style
+         * @returns a new style
+         * @see http://doc.babylonjs.com/how_to/gui#styles
          */
         public createStyle(): Style {
             return new Style(this);
         }
 
+        /**
+         * Adds a new control to the root container
+         * @param control defines the control to add
+         * @returns the current texture
+         */
         public addControl(control: Control): AdvancedDynamicTexture {
             this._rootContainer.addControl(control);
 
             return this;
         }
 
+        /**
+         * Removes a control from the root container
+         * @param control defines the control to remove
+         * @returns the current texture
+         */        
         public removeControl(control: Control): AdvancedDynamicTexture {
             this._rootContainer.removeControl(control);
             return this;
         }
 
+        /**
+         * Release all resources
+         */
         public dispose(): void {
             let scene = this.getScene();
 
@@ -316,11 +412,18 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         public _getGlobalViewport(scene: Scene): Viewport {
             var engine = scene.getEngine();
             return this._fullscreenViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
         }
 
+        /**
+         * Get screen coordinates for a vector3
+         * @param position defines the position to project
+         * @param worldMatrix defines the world matrix to use
+         * @returns the projected position
+         */
         public getProjectedPosition(position: Vector3, worldMatrix: Matrix): Vector2 {
             var scene = this.getScene();
 
@@ -446,6 +549,7 @@ module BABYLON.GUI {
             this._manageFocus();
         }
 
+        /** @hidden */
         public _cleanControlAfterRemovalFromList(list: {[pointerId:number]:Control}, control:Control) {
             for (var pointerId in list) {
                 if (!list.hasOwnProperty(pointerId)) {
@@ -459,11 +563,13 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         public _cleanControlAfterRemoval(control: Control) {
             this._cleanControlAfterRemovalFromList(this._lastControlDown, control);
             this._cleanControlAfterRemovalFromList(this._lastControlOver, control);
         }
 
+        /** Attach to all scene events required to support pointer events */
         public attach(): void {
             var scene = this.getScene();
             if (!scene) {
@@ -504,6 +610,11 @@ module BABYLON.GUI {
             this._attachToOnPointerOut(scene);
         }
 
+        /**
+         * Connect the texture to a hosting mesh to enable interactions
+         * @param mesh defines the mesh to attach to
+         * @param supportPointerMove defines a boolean indicating if pointer move events must be catched as well
+         */
         public attachToMesh(mesh: AbstractMesh, supportPointerMove = true): void {
             var scene = this.getScene();
             if (!scene) {
@@ -526,7 +637,7 @@ module BABYLON.GUI {
                     }
                 } else if (pi.type === BABYLON.PointerEventTypes.POINTERUP) {
                     if (this._lastControlDown[pointerId]) {
-                        this._lastControlDown[pointerId].forcePointerUp(pointerId);
+                        this._lastControlDown[pointerId]._forcePointerUp(pointerId);
                     }
                     delete this._lastControlDown[pointerId];
 
@@ -543,6 +654,10 @@ module BABYLON.GUI {
             this._attachToOnPointerOut(scene);
         }
 
+        /**
+         * Move the focus to a specific control
+         * @param control defines the control which will receive the focus
+         */
         public moveFocusToControl(control: IFocusableControl): void {
             this.focusedControl = control;
             this._lastPickedControl = <any>control;
@@ -576,13 +691,21 @@ module BABYLON.GUI {
                 delete this._lastControlOver[pointerEvent.pointerId];
 
                 if (this._lastControlDown[pointerEvent.pointerId]) {
-                    this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
+                    this._lastControlDown[pointerEvent.pointerId]._forcePointerUp();
                 }
                 delete this._lastControlDown[pointerEvent.pointerId];
             });
         }
 
         // Statics
+        /**
+         * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh)
+         * @param mesh defines the mesh which will receive the texture
+         * @param width defines the texture width (1024 by default)
+         * @param height defines the texture height (1024 by default)
+         * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+         * @returns a new AdvancedDynamicTexture
+         */
         public static CreateForMesh(mesh: AbstractMesh, width = 1024, height = 1024, supportPointerMove = true): AdvancedDynamicTexture {
             var result = new AdvancedDynamicTexture(mesh.name + " AdvancedDynamicTexture", width, height, mesh.getScene(), true, Texture.TRILINEAR_SAMPLINGMODE);
 
@@ -601,15 +724,16 @@ module BABYLON.GUI {
         }
 
         /**
-         * FullScreenUI is created in a layer. This allows it to be treated like any other layer.
+         * Creates a new AdvancedDynamicTexture in fullscreen mode.
+         * In this mode the texture will rely on a layer for its rendering.
+         * This allows it to be treated like any other layer.
          * As such, if you have a multi camera setup, you can set the layerMask on the GUI as well.
-         * When the GUI is not Created as FullscreenUI it does not respect the layerMask.
-         * layerMask is set through advancedTexture.layer.layerMask
-		 * @param name name for the Texture
-		 * @param foreground render in foreground (default is true)
-		 * @param scene scene to be rendered in
-		 * @param sampling method for scaling to fit screen
-		 * @returns AdvancedDynamicTexture
+         * LayerMask is set through advancedTexture.layer.layerMask
+		 * @param name defines name for the texture
+		 * @param foreground defines a boolean indicating if the texture must be rendered in foreground (default is true)
+		 * @param scene defines the hsoting scene
+		 * @param sampling defines the texture sampling mode (BABYLON.Texture.BILINEAR_SAMPLINGMODE by default)
+		 * @returns a new AdvancedDynamicTexture
          */
         public static CreateFullscreenUI(name: string, foreground: boolean = true, scene: Nullable<Scene> = null, sampling = Texture.BILINEAR_SAMPLINGMODE): AdvancedDynamicTexture {
             var result = new AdvancedDynamicTexture(name, 0, 0, scene, false, sampling);

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

@@ -1,12 +1,31 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create 2D buttons
+     */
     export class Button extends Rectangle {    
+        /**
+         * Function called to generate a pointer enter animation
+         */
         public pointerEnterAnimation: () => void;
+        /**
+         * Function called to generate a pointer out animation
+         */        
         public pointerOutAnimation: () => void;
+        /**
+         * Function called to generate a pointer down animation
+         */        
         public pointerDownAnimation: () => void;
+        /**
+         * Function called to generate a pointer up animation
+         */        
         public pointerUpAnimation: () => void;
 
+        /**
+         * Creates a new Button
+         * @param name defines the name of the button
+         */
         constructor(public name?: string) {
             super(name);
           
@@ -37,6 +56,7 @@ module BABYLON.GUI {
         }
 
         // While being a container, the button behaves like a control.
+        /** @hidden */
         public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
             if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
                 return false;
@@ -51,6 +71,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerEnter(target: Control): boolean {
             if (!super._onPointerEnter(target)) {
                 return false;
@@ -63,6 +84,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerOut(target: Control): void {
             if (this.pointerOutAnimation) {
                 this.pointerOutAnimation();
@@ -71,6 +93,7 @@ module BABYLON.GUI {
             super._onPointerOut(target);
         }
 
+        /** @hidden */
         public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
             if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
                 return false;
@@ -84,6 +107,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
             if (this.pointerUpAnimation) {
                 this.pointerUpAnimation();
@@ -93,6 +117,13 @@ module BABYLON.GUI {
         }        
 
         // Statics
+        /**
+         * Creates a new button made with an image and a text
+         * @param name defines the name of the button
+         * @param text defines the text of the button
+         * @param imageUrl defines the url of the image
+         * @returns a new Button
+         */
         public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
             var result = new Button(name);
 
@@ -113,6 +144,12 @@ module BABYLON.GUI {
             return result;
         }
 
+        /**
+         * Creates a new button made with an image
+         * @param name defines the name of the button
+         * @param imageUrl defines the url of the image
+         * @returns a new Button
+         */
         public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
             var result = new Button(name);
 
@@ -125,6 +162,12 @@ module BABYLON.GUI {
             return result;
         }
 
+        /**
+         * Creates a new button made with a text
+         * @param name defines the name of the button
+         * @param text defines the text of the button
+         * @returns a new Button
+         */        
         public static CreateSimpleButton(name: string, text: string): Button {
             var result = new Button(name);
 
@@ -137,6 +180,13 @@ module BABYLON.GUI {
             return result;
         }
         
+        /**
+         * Creates a new button made with an image and a centered text
+         * @param name defines the name of the button
+         * @param text defines the text of the button
+         * @param imageUrl defines the url of the image
+         * @returns a new Button
+         */        
         public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
             var result = new Button(name);
 

+ 17 - 0
gui/src/2D/controls/checkbox.ts

@@ -1,12 +1,16 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to represent a 2D checkbox
+     */
     export class Checkbox extends Control {
         private _isChecked = false;
         private _background = "black";   
         private _checkSizeRatio = 0.8;
         private _thickness = 1;
         
+        /** Gets or sets border thickness  */
         public get thickness(): number {
             return this._thickness;
         }
@@ -20,8 +24,12 @@ module BABYLON.GUI {
             this._markAsDirty();
         }           
 
+        /**
+         * Observable raised when isChecked property changes
+         */
         public onIsCheckedChangedObservable = new Observable<boolean>();
 
+        /** Gets or sets a value indicating the ratio between overall size and check size */
         public get checkSizeRatio(): number {
             return this._checkSizeRatio;
         }
@@ -37,6 +45,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }             
 
+        /** Gets or sets background color */
         public get background(): string {
             return this._background;
         }
@@ -50,6 +59,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }     
 
+        /** Gets or sets a boolean indicating if the checkbox is checked or not */
         public get isChecked(): boolean {
             return this._isChecked;
         }
@@ -65,6 +75,10 @@ module BABYLON.GUI {
             this.onIsCheckedChangedObservable.notifyObservers(value);
         }                             
 
+        /**
+         * Creates a new CheckBox
+         * @param name defines the control name
+         */
         constructor(public name?: string) {
             super(name);
             this.isPointerBlocker = true;
@@ -74,6 +88,7 @@ module BABYLON.GUI {
             return "CheckBox";
         }
         
+        /** @hidden */
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             context.save();
 
@@ -115,6 +130,8 @@ module BABYLON.GUI {
         }
 
         // Events
+
+        /** @hidden */
         public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
             if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
                 return false;

+ 13 - 0
gui/src/2D/controls/colorpicker.ts

@@ -1,6 +1,7 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /** Class used to create color pickers */
     export class ColorPicker extends Control {
         private _colorWheelCanvas: HTMLCanvasElement;
         
@@ -18,8 +19,12 @@ module BABYLON.GUI {
         private _s = 1;
         private _v = 1;
         
+        /**
+         * Observable raised when the value changes
+         */
         public onValueChangedObservable = new Observable<Color3>();
 
+        /** Gets or sets the color of the color picker */
         public get value(): Color3 {
             return this._value;
         }
@@ -42,6 +47,7 @@ module BABYLON.GUI {
             this.onValueChangedObservable.notifyObservers(this._value);
         }
 
+        /** Gets or sets control width */
         public set width(value: string | number ) {
             if (this._width.toString(this._host) === value) {
                 return;
@@ -53,6 +59,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets control height */
         public set height(value: string | number ) {
             if (this._height.toString(this._host) === value) {
                 return;
@@ -64,6 +71,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets control size */
         public get size(): string | number {
             return this.width;
         }
@@ -72,6 +80,10 @@ module BABYLON.GUI {
             this.width = value;
         }              
 
+        /**
+         * Creates a new ColorPicker
+         * @param name defines the control name
+         */
         constructor(public name?: string) {
             super(name);
             this.value = new BABYLON.Color3(.88, .1, .1);
@@ -259,6 +271,7 @@ module BABYLON.GUI {
             result.set((r+m), (g+m), (b+m));            
         }
 
+        /** @hidden */
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             context.save();
 

+ 58 - 1
gui/src/2D/controls/container.ts

@@ -1,13 +1,23 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Root class for 2D containers
+     * @see http://doc.babylonjs.com/how_to/gui#containers
+     */
     export class Container extends Control {
+        /** @hidden */
         protected _children = new Array<Control>();
+        /** @hidden */
         protected _measureForChildren = Measure.Empty();  
+        /** @hidden */
         protected _background: string;   
+        /** @hidden */
         protected _adaptWidthToChildren = false;
+        /** @hidden */
         protected _adaptHeightToChildren = false;
 
+        /** Gets or sets a boolean indicating if the container should try to adapt to its children height */
         public get adaptHeightToChildren(): boolean {
             return this._adaptHeightToChildren;
         }
@@ -26,6 +36,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }       
         
+        /** Gets or sets a boolean indicating if the container should try to adapt to its children width */
         public get adaptWidthToChildren(): boolean {
             return this._adaptWidthToChildren;
         }
@@ -44,6 +55,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }           
 
+        /** Gets or sets background color */
         public get background(): string {
             return this._background;
         }
@@ -57,10 +69,15 @@ module BABYLON.GUI {
             this._markAsDirty();
         }  
 
+        /** Gets the list of children */
         public get children(): Control[] {
             return this._children;
         }        
 
+        /**
+         * Creates a new Container
+         * @param name defines the name of the container
+         */
         constructor(public name?: string) {
             super(name);
         }
@@ -69,6 +86,11 @@ module BABYLON.GUI {
             return "Container";
         }           
 
+        /**
+         * Gets a child using its name
+         * @param name defines the child name to look for
+         * @returns the child control if found
+         */
         public getChildByName(name: string): Nullable<Control> {
             for (var child of this._children) {
                 if (child.name === name) {
@@ -79,6 +101,12 @@ module BABYLON.GUI {
             return null;
         }       
 
+        /**
+         * Gets a child using its type and its name
+         * @param name defines the child name to look for
+         * @param type defines the child type to look for
+         * @returns the child control if found
+         */        
         public getChildByType(name: string, type: string): Nullable<Control> {
             for (var child of this._children) {
                 if (child.typeName === type) {
@@ -89,11 +117,25 @@ module BABYLON.GUI {
             return null;
         }            
 
+        /**
+         * Search for a specific control in children
+         * @param control defines the control to look for
+         * @returns true if the control is in child list
+         */
         public containsControl(control: Control): boolean {
             return this._children.indexOf(control) !== -1;
         }
 
-        public addControl(control: Control): Container {
+        /**
+         * Adds a new control to the current container
+         * @param control defines the control to add
+         * @returns the current container
+         */
+        public addControl(control: Nullable<Control>): Container {
+            if (!control) {
+                return this;
+            }
+
            var index = this._children.indexOf(control);
 
             if (index !== -1) {
@@ -109,6 +151,11 @@ module BABYLON.GUI {
             return this;
         }
 
+        /**
+         * Removes a control from the current container
+         * @param control defines the control to remove
+         * @returns the current container
+         */        
         public removeControl(control: Control): Container {
             var index = this._children.indexOf(control);
 
@@ -128,6 +175,7 @@ module BABYLON.GUI {
             return this;
         }
 
+        /** @hidden */
         public _reOrderControl(control: Control): void {
             this.removeControl(control);
 
@@ -145,6 +193,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** @hidden */       
         public _markMatrixAsDirty(): void {
             super._markMatrixAsDirty();
 
@@ -153,6 +202,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */ 
         public _markAllAsDirty(): void {
             super._markAllAsDirty();
 
@@ -161,6 +211,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */ 
         protected _localDraw(context: CanvasRenderingContext2D): void {
             if (this._background) {
                 if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
@@ -181,6 +232,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */ 
         public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
             super._link(root, host);
 
@@ -189,6 +241,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */ 
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {      
             if (!this.isVisible || this.notRenderable) {
                 return;
@@ -237,6 +290,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */ 
         public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
             if (!this.isVisible || this.notRenderable) {
                 return false;
@@ -261,16 +315,19 @@ module BABYLON.GUI {
             return this._processObservables(type, x, y, pointerId, buttonIndex);
         }
 
+        /** @hidden */ 
         protected _clipForChildren(context: CanvasRenderingContext2D): void {
             // DO nothing
         }
 
+        /** @hidden */ 
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
             super._additionalProcessing(parentMeasure, context);
 
             this._measureForChildren.copyFrom(this._currentMeasure);
         }
 
+        /** Releases associated resources */
         public dispose() {
             super.dispose();
 

+ 253 - 8
gui/src/2D/controls/control.ts

@@ -1,34 +1,52 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Root class used for all 2D controls
+     * @see http://doc.babylonjs.com/how_to/gui#controls
+     */
     export class Control {
         private _alpha = 1;
         private _alphaSet = false;
         private _zIndex = 0;
+        /** @hidden */
         public _root: Nullable<Container>;
+        /** @hidden */
         public _host: AdvancedDynamicTexture;
+        /** Gets or sets the control parent */
         public parent: Nullable<Container>;
+        /** @hidden */
         public _currentMeasure = Measure.Empty();
         private _fontFamily = "Arial";
         private _fontStyle = "";
+        private _fontWeight = "";
         private _fontSize = new ValueAndUnit(18, ValueAndUnit.UNITMODE_PIXEL, false);
         private _font: string;
+        /** @hidden */
         public _width = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
+        /** @hidden */
         public _height = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
+        /** @hidden */
         protected _fontOffset: { ascent: number, height: number, descent: number };
         private _color = "";
         private _style: BABYLON.Nullable<Style> = null;
         private _styleObserver: BABYLON.Nullable<BABYLON.Observer<Style>>;
+        /** @hidden */
         protected _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        /** @hidden */
         protected _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
         private _isDirty = true;
+        /** @hidden */
         public _tempParentMeasure = Measure.Empty();
+        /** @hidden */
         protected _cachedParentMeasure = Measure.Empty();
         private _paddingLeft = new ValueAndUnit(0);
         private _paddingRight = new ValueAndUnit(0);
         private _paddingTop = new ValueAndUnit(0);
         private _paddingBottom = new ValueAndUnit(0);
+        /** @hidden */
         public _left = new ValueAndUnit(0);
+        /** @hidden */
         public _top = new ValueAndUnit(0);
         private _scaleX = 1.0;
         private _scaleY = 1.0;
@@ -36,35 +54,48 @@ module BABYLON.GUI {
         private _transformCenterX = 0.5;
         private _transformCenterY = 0.5;
         private _transformMatrix = Matrix2D.Identity();
+        /** @hidden */
         protected _invertTransformMatrix = Matrix2D.Identity();
+        /** @hidden */
         protected _transformedPosition = Vector2.Zero();
         private _onlyMeasureMode = false;
         private _isMatrixDirty = true;
         private _cachedOffsetX: number;
         private _cachedOffsetY: number;
         private _isVisible = true;
+        /** @hidden */
         public _linkedMesh: Nullable<AbstractMesh>;
         private _fontSet = false;
         private _dummyVector2 = Vector2.Zero();
         private _downCount = 0;
-        private _enterCount = 0;
+        private _enterCount = -1;
         private _doNotRender = false;
         private _downPointerIds:{[id:number] : boolean} = {};
 
+        /** Gets or sets a boolean indicating if the control can be hit with pointer events */
         public isHitTestVisible = true;
+        /** Gets or sets a boolean indicating if the control can block pointer events */
         public isPointerBlocker = false;
+        /** Gets or sets a boolean indicating if the control can be focusable */
         public isFocusInvisible = false;
 
+        /** Gets or sets a value indicating the offset to apply on X axis to render the shadow */
         public shadowOffsetX = 0;
+        /** Gets or sets a value indicating the offset to apply on Y axis to render the shadow */
         public shadowOffsetY = 0;
+        /** Gets or sets a value indicating the amount of blur to use to render the shadow */
         public shadowBlur = 0;
+        /** Gets or sets a value indicating the color of the shadow (black by default ie. "#000") */
         public shadowColor = '#000';
 
+         /** @hidden */
         protected _linkOffsetX = new ValueAndUnit(0);
+         /** @hidden */
         protected _linkOffsetY = new ValueAndUnit(0);
 
         // Properties
 
+        /** Gets the control type name */
         public get typeName(): string {
             return this._getTypeName();
         }
@@ -118,6 +149,7 @@ module BABYLON.GUI {
             this._fontOffset = offset;
         }
 
+        /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
         public get alpha(): number {
             return this._alpha;
         }
@@ -131,6 +163,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets a value indicating the scale factor on X axis (1 by default) 
+         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+        */
         public get scaleX(): number {
             return this._scaleX;
         }
@@ -145,6 +180,9 @@ module BABYLON.GUI {
             this._markMatrixAsDirty();
         }
 
+        /** Gets or sets a value indicating the scale factor on Y axis (1 by default) 
+         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+        */
         public get scaleY(): number {
             return this._scaleY;
         }
@@ -159,6 +197,9 @@ module BABYLON.GUI {
             this._markMatrixAsDirty();
         }
 
+        /** Gets or sets the rotation angle (0 by default) 
+         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+        */
         public get rotation(): number {
             return this._rotation;
         }
@@ -173,6 +214,9 @@ module BABYLON.GUI {
             this._markMatrixAsDirty();
         }
 
+        /** Gets or sets the transformation center on Y axis (0 by default)
+         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+        */
         public get transformCenterY(): number {
             return this._transformCenterY;
         }
@@ -187,6 +231,9 @@ module BABYLON.GUI {
             this._markMatrixAsDirty();
         }
 
+        /** Gets or sets the transformation center on X axis (0 by default)
+         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+        */
         public get transformCenterX(): number {
             return this._transformCenterX;
         }
@@ -201,6 +248,10 @@ module BABYLON.GUI {
             this._markMatrixAsDirty();
         }
 
+        /** 
+         * Gets or sets the horizontal alignment 
+         * @see http://doc.babylonjs.com/how_to/gui#alignments
+         */
         public get horizontalAlignment(): number {
             return this._horizontalAlignment;
         }
@@ -214,6 +265,10 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** 
+         * Gets or sets the vertical alignment 
+         * @see http://doc.babylonjs.com/how_to/gui#alignments
+         */        
         public get verticalAlignment(): number {
             return this._verticalAlignment;
         }
@@ -227,10 +282,18 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** 
+         * Gets or sets control width 
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */
         public get width(): string | number {
             return this._width.toString(this._host);
         }
 
+        /** 
+         * Gets control width in pixel
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get widthInPixels(): number {
             return this._width.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -245,10 +308,18 @@ module BABYLON.GUI {
             }
         }
 
+        /** 
+         * Gets or sets control height 
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get height(): string | number {
             return this._height.toString(this._host);
         }
 
+        /** 
+         * Gets control height in pixel
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get heightInPixels(): number {
             return this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
         }
@@ -263,6 +334,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or set font family */
         public get fontFamily(): string {
             return this._fontFamily;
         }
@@ -276,6 +348,7 @@ module BABYLON.GUI {
             this._resetFontCache();
         }
 
+        /** Gets or sets font style */
         public get fontStyle(): string {
             return this._fontStyle;
         }
@@ -289,6 +362,24 @@ module BABYLON.GUI {
             this._resetFontCache();
         }
 
+        /** Gets or sets font weight */
+        public get fontWeight(): string {
+            return this._fontWeight;
+        }
+
+        public set fontWeight(value: string) {
+            if (this._fontWeight === value) {
+                return;
+            }
+
+            this._fontWeight = value;
+            this._resetFontCache();
+        }        
+
+        /**
+         * Gets or sets style
+         * @see http://doc.babylonjs.com/how_to/gui#styles
+         */
         public get style(): BABYLON.Nullable<Style> {
             return this._style;
         }
@@ -317,6 +408,7 @@ module BABYLON.GUI {
             return this._fontSize.isPercentage;
         }
 
+        /** Gets font size in pixels */
         public get fontSizeInPixels(): number {
             let fontSizeToUse =  this._style ? this._style._fontSize : this._fontSize;
 
@@ -327,6 +419,7 @@ module BABYLON.GUI {
             return fontSizeToUse.getValueInPixel(this._host, this._tempParentMeasure.height || this._cachedParentMeasure.height);
         }
 
+        /** Gets or sets font size */
         public get fontSize(): string | number {
             return this._fontSize.toString(this._host);
         }
@@ -342,6 +435,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets foreground color */
         public get color(): string {
             return this._color;
         }
@@ -355,6 +449,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets z index which is used to reorder controls on the z axis */
         public get zIndex(): number {
             return this._zIndex;
         }
@@ -371,6 +466,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets a boolean indicating if the control can be rendered */
         public get notRenderable(): boolean {
             return this._doNotRender;
         }
@@ -384,6 +480,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets a boolean indicating if the control is visible */
         public get isVisible(): boolean {
             return this._isVisible;
         }
@@ -397,14 +494,23 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets a boolean indicating that the control needs to update its rendering */
         public get isDirty(): boolean {
             return this._isDirty;
         }
 
+        /**
+         * Gets or sets a value indicating the padding to use on the left of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */
         public get paddingLeft(): string | number {
             return this._paddingLeft.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the padding in pixels to use on the left of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get paddingLeftInPixels(): number {
             return this._paddingLeft.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -415,10 +521,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the padding to use on the right of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get paddingRight(): string | number {
             return this._paddingRight.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the padding in pixels to use on the right of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */        
         public get paddingRightInPixels(): number {
             return this._paddingRight.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -429,10 +543,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the padding to use on the top of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */                
         public get paddingTop(): string | number {
             return this._paddingTop.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the padding in pixels to use on the top of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */                
         public get paddingTopInPixels(): number {
             return this._paddingTop.getValueInPixel(this._host, this._cachedParentMeasure.height);
         }
@@ -443,10 +565,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the padding to use on the bottom of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */                
         public get paddingBottom(): string | number {
             return this._paddingBottom.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the padding in pixels to use on the bottom of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */  
         public get paddingBottomInPixels(): number {
             return this._paddingBottom.getValueInPixel(this._host, this._cachedParentMeasure.height);
         }
@@ -457,10 +587,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the left coordinate of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */  
         public get left(): string | number {
             return this._left.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the left coordinate in pixels of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */         
         public get leftInPixels(): number {
             return this._left.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -471,10 +609,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the top coordinate of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */         
         public get top(): string | number {
             return this._top.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the top coordinate in pixels of the control
+         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         */           
         public get topInPixels(): number {
             return this._top.getValueInPixel(this._host, this._cachedParentMeasure.height);
         }
@@ -485,10 +631,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the offset on X axis to the linked mesh
+         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         */
         public get linkOffsetX(): string | number {
             return this._linkOffsetX.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the offset in pixels on X axis to the linked mesh
+         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         */        
         public get linkOffsetXInPixels(): number {
             return this._linkOffsetX.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -499,10 +653,18 @@ module BABYLON.GUI {
             }
         }
 
+        /**
+         * Gets or sets a value indicating the offset on Y axis to the linked mesh
+         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         */        
         public get linkOffsetY(): string | number {
             return this._linkOffsetY.toString(this._host);
         }
 
+        /**
+         * Gets a value indicating the offset in pixels on Y axis to the linked mesh
+         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         */         
         public get linkOffsetYInPixels(): number {
             return this._linkOffsetY.getValueInPixel(this._host, this._cachedParentMeasure.height);
         }
@@ -513,18 +675,28 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets the center coordinate on X axis */
         public get centerX(): number {
             return this._currentMeasure.left + this._currentMeasure.width / 2;
         }
 
+        /** Gets the center coordinate on Y axis */
         public get centerY(): number {
             return this._currentMeasure.top + this._currentMeasure.height / 2;
         }
 
         // Functions
-        constructor(public name?: string) {
+
+        /**
+         * Creates a new control
+         * @param name defines the name of the control
+         */
+        constructor(
+            /** defines the name of the control */
+            public name?: string) {
         }
 
+        /** @hidden */
         protected _getTypeName(): string {
             return "Control";
         }
@@ -534,6 +706,11 @@ module BABYLON.GUI {
             this._fontSet = true;
         }
 
+        /** 
+         * Gets coordinates in local control space 
+         * @param globalCoordinates defines the coordinates to transform
+         * @returns the new coordinates in local space
+         */
         public getLocalCoordinates(globalCoordinates: Vector2): Vector2 {
             var result = Vector2.Zero();
 
@@ -542,12 +719,23 @@ module BABYLON.GUI {
             return result;
         }
 
+        /** 
+         * Gets coordinates in local control space 
+         * @param globalCoordinates defines the coordinates to transform
+         * @param result defines the target vector2 where to store the result
+         * @returns the current control
+         */        
         public getLocalCoordinatesToRef(globalCoordinates: Vector2, result: Vector2): Control {
             result.x = globalCoordinates.x - this._currentMeasure.left;
             result.y = globalCoordinates.y - this._currentMeasure.top;
             return this;
         }
 
+        /** 
+         * Gets coordinates in parent local control space 
+         * @param globalCoordinates defines the coordinates to transform
+         * @returns the new coordinates in parent local space
+         */
         public getParentLocalCoordinates(globalCoordinates: Vector2): Vector2 {
             var result = Vector2.Zero();
 
@@ -557,6 +745,11 @@ module BABYLON.GUI {
             return result;
         }
 
+        /**
+         * Move the current control to a vector3 position projected onto the screen.
+         * @param position defines the target position
+         * @param scene defines the hosting scene
+         */
         public moveToVector3(position: Vector3, scene: Scene): void {
             if (!this._host || this._root !== this._host._rootContainer) {
                 Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
@@ -578,6 +771,11 @@ module BABYLON.GUI {
             this.notRenderable = false;
         }
 
+        /**
+         * Link current control with a target mesh
+         * @param mesh defines the mesh to link with
+         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         */
         public linkWithMesh(mesh: Nullable<AbstractMesh>): void {
             if (!this._host || this._root && this._root !== this._host._rootContainer) {
                 if (mesh) {
@@ -604,6 +802,7 @@ module BABYLON.GUI {
             this._host._linkedControls.push(this);
         }
 
+        /** @hidden */
         public _moveToProjectedPosition(projectedPosition: Vector3): void {
             let oldLeft = this._left.getValue(this._host);
             let oldTop = this._top.getValue(this._host);
@@ -628,11 +827,13 @@ module BABYLON.GUI {
             this._top.ignoreAdaptiveScaling = true;
         }
 
+        /** @hidden */
         public _markMatrixAsDirty(): void {
             this._isMatrixDirty = true;
             this._markAsDirty();
         }
 
+        /** @hidden */
         public _markAsDirty(): void {
             this._isDirty = true;
 
@@ -642,6 +843,7 @@ module BABYLON.GUI {
             this._host.markAsDirty();
         }
 
+        /** @hidden */
         public _markAllAsDirty(): void {
             this._markAsDirty();
 
@@ -650,11 +852,13 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
             this._root = root;
             this._host = host;
         }
 
+        /** @hidden */
         protected _transform(context: CanvasRenderingContext2D): void {
             if (!this._isMatrixDirty && this._scaleX === 1 && this._scaleY === 1 && this._rotation === 0) {
                 return;
@@ -686,6 +890,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         protected _applyStates(context: CanvasRenderingContext2D): void {
             if (this._fontSet) {
                 this._prepareFont();
@@ -705,6 +910,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean {
             if (this._isDirty || !this._cachedParentMeasure.isEqualsTo(parentMeasure)) {
                 this._isDirty = false;
@@ -763,6 +969,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         protected _clip(context: CanvasRenderingContext2D) {
             context.beginPath();
 
@@ -785,6 +992,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         public _measure(): void {
             // Width / Height
             if (this._width.isPixel) {
@@ -800,6 +1008,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             var width = this._currentMeasure.width;
             var height = this._currentMeasure.height;
@@ -879,18 +1088,27 @@ module BABYLON.GUI {
             this._currentMeasure.top += y;
         }
 
+        /** @hidden */
         protected _preMeasure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             // Do nothing
         }
 
+        /** @hidden */
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             // Do nothing
         }
 
+        /** @hidden */
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             // Do nothing
         }
 
+        /**
+         * Tests if a given coordinates belong to the current control
+         * @param x defines x coordinate to test
+         * @param y defines y coordinate to test
+         * @returns true if the coordinates are inside the control
+         */
         public contains(x: number, y: number): boolean {
             // Invert transform
             this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
@@ -921,6 +1139,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
             if (!this.isHitTestVisible || !this.isVisible || this._doNotRender) {
                 return false;
@@ -935,17 +1154,22 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerMove(target: Control, coordinates: Vector2): void {
             var canNotify: boolean = this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
 
             if (canNotify && this.parent != null) this.parent._onPointerMove(target, coordinates);
         }
 
+        /** @hidden */
         public _onPointerEnter(target: Control): boolean {
-            if (this._enterCount !== 0) {
+            if (this._enterCount > 0) {
                 return false;
             }
 
+            if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
+                this._enterCount = 0;
+            }
             this._enterCount++;
 
             var canNotify: boolean = this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
@@ -955,6 +1179,7 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerOut(target: Control): void {
             this._enterCount = 0;
 
@@ -963,6 +1188,7 @@ module BABYLON.GUI {
             if (canNotify && this.parent != null) this.parent._onPointerOut(target);
         }
 
+        /** @hidden */
         public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
             if (this._downCount !== 0) {
                 return false;
@@ -979,13 +1205,14 @@ module BABYLON.GUI {
             return true;
         }
 
+        /** @hidden */
         public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
             this._downCount = 0;
 
             delete this._downPointerIds[pointerId];
 
             var canNotifyClick: boolean = notifyClick;
-			if (notifyClick && this._enterCount > 0) {
+			if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
 				canNotifyClick = this.onPointerClickObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
 			}
 			var canNotify: boolean = this.onPointerUpObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
@@ -993,7 +1220,8 @@ module BABYLON.GUI {
             if (canNotify && this.parent != null) this.parent._onPointerUp(target, coordinates, pointerId, buttonIndex, canNotifyClick);
         }
 
-        public forcePointerUp(pointerId:Nullable<number> = null) {
+        /** @hidden */
+        public _forcePointerUp(pointerId:Nullable<number> = null) {
             if(pointerId !== null){
                 this._onPointerUp(this, Vector2.Zero(), pointerId, 0, true);
             }else{
@@ -1003,6 +1231,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */
         public _processObservables(type: number, x: number, y: number, pointerId:number, buttonIndex: number): boolean {
             this._dummyVector2.copyFromFloats(x, y);
             if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
@@ -1039,21 +1268,21 @@ module BABYLON.GUI {
             return false;
         }
 
-
         private _prepareFont() {
             if (!this._font && !this._fontSet) {
                 return;
             }
 
             if (this._style) {
-                this._font = this._style.fontStyle + " " + this.fontSizeInPixels + "px " + this._style.fontFamily;
+                this._font = (this._style.fontWeight ? this._style.fontWeight : this._style.fontStyle) + " " + this.fontSizeInPixels + "px " + this._style.fontFamily;
             } else {
-                this._font = this._fontStyle + " " + this.fontSizeInPixels + "px " + this._fontFamily;
+                this._font = (this._fontWeight ? this._fontWeight : this._fontStyle) + " " + this.fontSizeInPixels + "px " + this._fontFamily;
             }
 
             this._fontOffset = Control._GetFontOffset(this._font);
         }
 
+        /** Releases associated resources */
         public dispose() {
             this.onDirtyObservable.clear();
             this.onAfterDrawObservable.clear();
@@ -1089,32 +1318,39 @@ module BABYLON.GUI {
         private static _VERTICAL_ALIGNMENT_BOTTOM = 1;
         private static _VERTICAL_ALIGNMENT_CENTER = 2;
 
+        /** HORIZONTAL_ALIGNMENT_LEFT */
         public static get HORIZONTAL_ALIGNMENT_LEFT(): number {
             return Control._HORIZONTAL_ALIGNMENT_LEFT;
         }
 
+        /** HORIZONTAL_ALIGNMENT_RIGHT */
         public static get HORIZONTAL_ALIGNMENT_RIGHT(): number {
             return Control._HORIZONTAL_ALIGNMENT_RIGHT;
         }
 
+        /** HORIZONTAL_ALIGNMENT_CENTER */
         public static get HORIZONTAL_ALIGNMENT_CENTER(): number {
             return Control._HORIZONTAL_ALIGNMENT_CENTER;
         }
 
+        /** VERTICAL_ALIGNMENT_TOP */
         public static get VERTICAL_ALIGNMENT_TOP(): number {
             return Control._VERTICAL_ALIGNMENT_TOP;
         }
 
+        /** VERTICAL_ALIGNMENT_BOTTOM */
         public static get VERTICAL_ALIGNMENT_BOTTOM(): number {
             return Control._VERTICAL_ALIGNMENT_BOTTOM;
         }
 
+        /** VERTICAL_ALIGNMENT_CENTER */
         public static get VERTICAL_ALIGNMENT_CENTER(): number {
             return Control._VERTICAL_ALIGNMENT_CENTER;
         }
 
         private static _FontHeightSizes: { [key: string]: { ascent: number, height: number, descent: number } } = {};
 
+        /** @hidden */
         public static _GetFontOffset(font: string): { ascent: number, height: number, descent: number } {
 
             if (Control._FontHeightSizes[font]) {
@@ -1152,6 +1388,14 @@ module BABYLON.GUI {
             return result;
         };
 
+        /**
+         * Creates a stack panel that can be used to render headers
+         * @param control defines the control to associate with the header
+         * @param text defines the text of the header
+         * @param size defines the size of the header
+         * @param options defines options used to configure the header
+         * @returns a new StackPanel
+         */
         public static AddHeader(control: Control, text: string, size: string | number, options: { isHorizontal: boolean, controlFirst: boolean }): StackPanel {
             let panel = new BABYLON.GUI.StackPanel("panel");
             let isHorizontal = options ? options.isHorizontal : true;
@@ -1186,6 +1430,7 @@ module BABYLON.GUI {
             return panel;
         }
 
+        /** @hidden */
         protected static drawEllipse(x: number, y: number, width: number, height: number, context: CanvasRenderingContext2D): void {
             context.translate(x, y);
             context.scale(width, height);

+ 6 - 0
gui/src/2D/controls/ellipse.ts

@@ -1,9 +1,11 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /** Class used to create 2D ellipse containers */
     export class Ellipse extends Container {
         private _thickness = 1;       
         
+        /** Gets or sets border thickness */
         public get thickness(): number {
             return this._thickness;
         }
@@ -17,6 +19,10 @@ module BABYLON.GUI {
             this._markAsDirty();
         }                
      
+        /**
+         * Creates a new Ellipse
+         * @param name defines the control name
+         */
         constructor(public name?: string) {
             super(name);
         }

+ 49 - 1
gui/src/2D/controls/image.ts

@@ -3,6 +3,9 @@
 var DOMImage = Image;
 
 module BABYLON.GUI {
+    /**
+     * Class used to create 2D images
+     */
     export class Image extends Control {
         private _domImage: HTMLImageElement;
         private _imageWidth: number;
@@ -21,6 +24,9 @@ module BABYLON.GUI {
         private _cellHeight: number = 0;
         private _cellId: number = -1;
 
+        /**
+         * Gets or sets the left coordinate in the source image
+         */
         public get sourceLeft(): number {
             return this._sourceLeft;
         }
@@ -35,6 +41,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets or sets the top coordinate in the source image
+         */        
         public get sourceTop(): number {
             return this._sourceTop;
         }
@@ -49,6 +58,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets or sets the width to capture in the source image
+         */        
         public get sourceWidth(): number {
             return this._sourceWidth;
         }
@@ -63,6 +75,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets or sets the height to capture in the source image
+         */        
         public get sourceHeight(): number {
             return this._sourceHeight;
         }
@@ -77,6 +92,10 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** 
+         * Gets or sets a boolean indicating if the image can force its container to adapt its size 
+         * @see http://doc.babylonjs.com/how_to/gui#image
+         */
         public get autoScale(): boolean {
             return this._autoScale;
         }
@@ -93,6 +112,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets the streching mode used by the image */
         public get stretch(): number {
             return this._stretch;
         }
@@ -107,6 +127,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets or sets the internal DOM image used to render the control
+         */
         public set domImage(value: HTMLImageElement) {
             this._domImage = value;
             this._loaded = false;
@@ -136,6 +159,9 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets or sets image source url
+         */
         public set source(value: Nullable<string>) {
             if (this._source === value) {
                 return;
@@ -155,6 +181,10 @@ module BABYLON.GUI {
             }
         }
 
+        /** 
+         * Gets or sets the cell width to use when animation sheet is enabled 
+         * @see http://doc.babylonjs.com/how_to/gui#image
+         */
         get cellWidth(): number {
             return this._cellWidth;
         }
@@ -167,6 +197,10 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** 
+         * Gets or sets the cell height to use when animation sheet is enabled 
+         * @see http://doc.babylonjs.com/how_to/gui#image
+         */
         get cellHeight(): number {
             return this._cellHeight;
         }
@@ -178,7 +212,11 @@ module BABYLON.GUI {
             this._cellHeight = value;
             this._markAsDirty();
         }
-
+    
+        /** 
+         * Gets or sets the cell id to use (this will turn on the animation sheet mode)
+         * @see http://doc.babylonjs.com/how_to/gui#image
+         */
         get cellId(): number {
             return this._cellId;
         }
@@ -191,6 +229,11 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Creates a new Image
+         * @param name defines the control name
+         * @param url defines the image url
+         */
         constructor(public name?: string, url: Nullable<string> = null) {
             super(name);
 
@@ -201,6 +244,7 @@ module BABYLON.GUI {
             return "Image";
         }
 
+        /** Force the control to synchronize with its content */
         public synchronizeSizeWithContent() {
             if (!this._loaded) {
                 return;
@@ -284,18 +328,22 @@ module BABYLON.GUI {
         private static _STRETCH_UNIFORM = 2;
         private static _STRETCH_EXTEND = 3;
 
+        /** STRETCH_NONE */
         public static get STRETCH_NONE(): number {
             return Image._STRETCH_NONE;
         }
 
+        /** STRETCH_FILL */
         public static get STRETCH_FILL(): number {
             return Image._STRETCH_FILL;
         }
 
+        /** STRETCH_UNIFORM */
         public static get STRETCH_UNIFORM(): number {
             return Image._STRETCH_UNIFORM;
         }
 
+        /** STRETCH_EXTEND */
         public static get STRETCH_EXTEND(): number {
             return Image._STRETCH_EXTEND;
         }

+ 28 - 0
gui/src/2D/controls/inputText.ts

@@ -1,6 +1,9 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create input text control
+     */
     export class InputText extends Control implements IFocusableControl {
         private _text = "";
         private _placeholderText = "";
@@ -19,16 +22,22 @@ module BABYLON.GUI {
         private _textWidth: number;
         private _clickedCoordinate: Nullable<number>;
 
+        /** Gets or sets a string representing the message displayed on mobile when the control gets the focus */
         public promptMessage = "Please enter text:";
 
+        /** Observable raised when the text changes */
         public onTextChangedObservable = new Observable<InputText>();
+        /** Observable raised when the control gets the focus */
         public onFocusObservable = new Observable<InputText>();
+        /** Observable raised when the control loses the focus */
         public onBlurObservable = new Observable<InputText>();
 
+        /** Gets or sets the maximum width allowed by the control */
         public get maxWidth(): string | number {
             return this._maxWidth.toString(this._host);
         }
 
+        /** Gets the maximum width allowed by the control in pixels */
         public get maxWidthInPixels(): number {
             return this._maxWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -43,10 +52,12 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets control margin */
         public get margin(): string {
             return this._margin.toString(this._host);
         }
 
+        /** Gets control margin in pixels */
         public get marginInPixels(): number {
             return this._margin.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -61,6 +72,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets a boolean indicating if the control can auto stretch its width to adapt to the text */
         public get autoStretchWidth(): boolean {
             return this._autoStretchWidth;
         }
@@ -74,6 +86,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets border thickness */
         public get thickness(): number {
             return this._thickness;
         }
@@ -87,6 +100,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets the background color when focused */
         public get focusedBackground(): string {
             return this._focusedBackground;
         }
@@ -100,6 +114,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets the background color */
         public get background(): string {
             return this._background;
         }
@@ -113,6 +128,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets the placeholder color */
         public get placeholderColor(): string {
             return this._placeholderColor;
         }
@@ -126,6 +142,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets the text displayed when the control is empty */
         public get placeholderText(): string {
             return this._placeholderText;
         }
@@ -138,6 +155,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets the text displayed in the control */
         public get text(): string {
             return this._text;
         }
@@ -152,6 +170,7 @@ module BABYLON.GUI {
             this.onTextChangedObservable.notifyObservers(this);
         }
 
+        /** Gets or sets control width */
         public get width(): string | number {
             return this._width.toString(this._host);
         }
@@ -168,12 +187,18 @@ module BABYLON.GUI {
             this.autoStretchWidth = false;
         }
 
+        /**
+         * Creates a new InputText
+         * @param name defines the control name
+         * @param text defines the text of the control
+         */
         constructor(public name?: string, text: string = "") {
             super(name);
 
             this.text = text;
         }
 
+        /** @hidden */
         public onBlur(): void {
             this._isFocused = false;
             this._scrollLeft = null;
@@ -184,6 +209,7 @@ module BABYLON.GUI {
             this.onBlurObservable.notifyObservers(this);
         }
 
+        /** @hidden */
         public onFocus(): void {
             this._scrollLeft = null;
             this._isFocused = true;
@@ -208,6 +234,7 @@ module BABYLON.GUI {
             return "InputText";
         }
 
+        /** @hidden */
         public processKey(keyCode: number, key?: string) {
             // Specific cases
             switch (keyCode) {
@@ -283,6 +310,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** @hidden */       
         public processKeyboard(evt: KeyboardEvent): void {
             this.processKey(evt.keyCode, evt.key);
         }

+ 14 - 0
gui/src/2D/controls/line.ts

@@ -1,6 +1,7 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /** Class used to render 2D lines */
     export class Line extends Control {
         private _lineWidth = 1;
         private _x1 = new ValueAndUnit(0);
@@ -11,6 +12,7 @@ module BABYLON.GUI {
         private _connectedControl: Control;
         private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
 
+        /** Gets or sets the dash pattern */
         public get dash(): Array<number> {
             return this._dash;
         }
@@ -24,6 +26,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }     
 
+        /** Gets or sets the control connected with the line end */
         public get connectedControl(): Control {
             return this._connectedControl;
         }
@@ -46,6 +49,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }              
 
+        /** Gets or sets start coordinates on X axis */
         public get x1(): string | number  {
             return this._x1.toString(this._host);
         }
@@ -60,6 +64,7 @@ module BABYLON.GUI {
             }
         }    
 
+        /** Gets or sets start coordinates on Y axis */        
         public get y1(): string | number  {
             return this._y1.toString(this._host);
         }
@@ -74,6 +79,7 @@ module BABYLON.GUI {
             }
         }     
 
+        /** Gets or sets end coordinates on X axis */        
         public get x2(): string | number  {
             return this._x2.toString(this._host);
         }
@@ -88,6 +94,7 @@ module BABYLON.GUI {
             }
         }    
 
+        /** Gets or sets end coordinates on Y axis */        
         public get y2(): string | number  {
             return this._y2.toString(this._host);
         }
@@ -102,6 +109,7 @@ module BABYLON.GUI {
             }
         }                       
         
+        /** Gets or sets line width */
         public get lineWidth(): number {
             return this._lineWidth;
         }
@@ -115,10 +123,12 @@ module BABYLON.GUI {
             this._markAsDirty();
         }   
 
+        /** Gets or sets horizontal alignment */
         public set horizontalAlignment(value: number) {
             return;
         } 
 
+        /** Gets or sets vertical alignment */
         public set verticalAlignment(value: number) {
             return;
         }    
@@ -131,6 +141,10 @@ module BABYLON.GUI {
             return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
         }           
 
+        /**
+         * Creates a new Line
+         * @param name defines the control name
+         */
         constructor(public name?: string) {
             super(name);
 

+ 29 - 0
gui/src/2D/controls/multiLine.ts

@@ -2,6 +2,9 @@
 
 module BABYLON.GUI {
 
+    /**
+     * Class used to create multi line control
+     */
     export class MultiLine extends Control {
 
         private _lineWidth: number = 1;
@@ -13,6 +16,10 @@ module BABYLON.GUI {
         private _maxX: Nullable<number>;
         private _maxY: Nullable<number>;
 
+        /**
+         * Creates a new MultiLine
+         * @param name defines the control name
+         */
         constructor(public name?: string) {
             super(name);
 
@@ -24,6 +31,7 @@ module BABYLON.GUI {
             this._points = [];
         }
 
+        /** Gets or sets dash pattern */
         public get dash(): Array<number> {
             return this._dash;
         }
@@ -37,6 +45,11 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /**
+         * Gets point stored at specified index
+         * @param index defines the index to look for
+         * @returns the requested point if found
+         */
         public getAt(index: number): MultiLinePoint {
             if (!this._points[index]) {
                 this._points[index] = new MultiLinePoint(this);
@@ -45,14 +58,25 @@ module BABYLON.GUI {
             return this._points[index] as MultiLinePoint;
         }
 
+        /** Function called when a point is updated */
         public onPointUpdate = (): void => {
             this._markAsDirty();
         }
 
+        /**
+         * Adds new points to the point collection
+         * @param items defines the list of items (mesh, control or 2d coordiantes) to add 
+         * @returns the list of created MultiLinePoint
+         */
         public add(...items: (AbstractMesh | Control | { x: string | number, y: string | number })[]): MultiLinePoint[] {
             return items.map(item => this.push(item));
         }
 
+        /**
+         * Adds a new point to the point collection
+         * @param item defines the item (mesh, control or 2d coordiantes) to add 
+         * @returns the created MultiLinePoint
+         */
         public push(item?: (AbstractMesh | Control | { x: string | number, y: string | number })): MultiLinePoint {
             var point: MultiLinePoint = this.getAt(this._points.length);
 
@@ -72,6 +96,10 @@ module BABYLON.GUI {
             return point;
         }
 
+        /**
+         * Remove a specific value or point from the active point collection
+         * @param value defines the value or point to remove
+         */
         public remove(value: number | MultiLinePoint): void {
             var index: number;
             
@@ -97,6 +125,7 @@ module BABYLON.GUI {
             this._points.splice(index, 1);
         }
         
+        /** Gets or sets line width */
         public get lineWidth(): number {
             return this._lineWidth;
         }

+ 13 - 0
gui/src/2D/controls/radioButton.ts

@@ -1,12 +1,16 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create radio button controls
+     */
     export class RadioButton extends Control {
         private _isChecked = false;
         private _background = "black";   
         private _checkSizeRatio = 0.8;
         private _thickness = 1;
         
+        /** Gets or sets border thickness */
         public get thickness(): number {
             return this._thickness;
         }
@@ -20,10 +24,13 @@ module BABYLON.GUI {
             this._markAsDirty();
         }           
 
+        /** Gets or sets group name */
         public group = "";        
 
+        /** Observable raised when isChecked is changed */
         public onIsCheckedChangedObservable = new Observable<boolean>();
 
+        /** Gets or sets a value indicating the ratio between overall size and check size */
         public get checkSizeRatio(): number {
             return this._checkSizeRatio;
         }
@@ -39,6 +46,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }             
 
+        /** Gets or sets background color */
         public get background(): string {
             return this._background;
         }
@@ -52,6 +60,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }     
 
+        /** Gets or sets a boolean indicating if the checkbox is checked or not */
         public get isChecked(): boolean {
             return this._isChecked;
         }
@@ -84,6 +93,10 @@ module BABYLON.GUI {
             }
         }                             
 
+        /**
+         * Creates a new RadioButton
+         * @param name defines the control name
+         */        
         constructor(public name?: string) {
             super(name);
 

+ 8 - 1
gui/src/2D/controls/rectangle.ts

@@ -1,10 +1,12 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /** Class used to create rectangle container */
     export class Rectangle extends Container {
         private _thickness = 1;
         private _cornerRadius = 0;
         
+        /** Gets or sets border thickness */        
         public get thickness(): number {
             return this._thickness;
         }
@@ -18,6 +20,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }   
         
+        /** Gets or sets the corner radius angle */
         public get cornerRadius(): number {
             return this._cornerRadius;
         }
@@ -34,7 +37,11 @@ module BABYLON.GUI {
             this._cornerRadius = value;
             this._markAsDirty();
         }   
-       
+     
+        /**
+         * Creates a new Rectangle
+         * @param name defines the control name
+         */       
         constructor(public name?: string) {
             super(name);
         }

+ 19 - 3
gui/src/2D/controls/slider.ts

@@ -1,6 +1,9 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create slider controls
+     */
     export class Slider extends Control {
         private _thumbWidth = new ValueAndUnit(30, ValueAndUnit.UNITMODE_PIXEL, false);
         private _minimum = 0;
@@ -12,8 +15,10 @@ module BABYLON.GUI {
         private _isThumbCircle = false;
         private _isThumbClamped = false;
 
+        /** Observable raised when the sldier value changes */
         public onValueChangedObservable = new Observable<number>();
 
+        /** Gets or sets border color */
         public get borderColor(): string {
             return this._borderColor;
         }
@@ -27,6 +32,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets background color */
         public get background(): string {
             return this._background;
         }
@@ -40,10 +46,12 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
+        /** Gets or sets main bar offset */
         public get barOffset(): string | number {
             return this._barOffset.toString(this._host);
         }
 
+        /** Gets main bar offset in pixels*/
         public get barOffsetInPixels(): number {
             return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -58,10 +66,12 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets thumb width */
         public get thumbWidth(): string | number {
             return this._thumbWidth.toString(this._host);
         }
 
+        /** Gets thumb width in pixels */       
         public get thumbWidthInPixels(): number {
             return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
         }
@@ -76,6 +86,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets minimum value */
         public get minimum(): number {
             return this._minimum;
         }
@@ -91,6 +102,7 @@ module BABYLON.GUI {
             this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
         }
 
+        /** Gets or sets maximum value */        
         public get maximum(): number {
             return this._maximum;
         }
@@ -106,6 +118,7 @@ module BABYLON.GUI {
             this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
         }
 
+        /** Gets or sets current value */
         public get value(): number {
             return this._value;
         }
@@ -122,6 +135,7 @@ module BABYLON.GUI {
             this.onValueChangedObservable.notifyObservers(this._value);
         }
 
+        /** Gets or sets a boolean indicating if the thumb should be round or square */
         public get isThumbCircle(): boolean {
             return this._isThumbCircle;
         }
@@ -135,12 +149,11 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
-
+        /** Gets or sets a value indicating if the thumb can go over main bar extends */
         public get isThumbClamped(): boolean {
             return this._isThumbClamped;
         }
 
-
         public set isThumbClamped(value: boolean) {
             if (this._isThumbClamped === value) {
                 return;
@@ -150,7 +163,10 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
 
-
+       /**
+        * Creates a new Slider
+        * @param name defines the control name
+        */
         constructor(public name?: string) {
             super(name);
 

+ 10 - 0
gui/src/2D/controls/stackPanel.ts

@@ -1,6 +1,9 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create a 2D stack panel container
+     */
     export class StackPanel extends Container {
         private _isVertical = true;
         private _manualWidth = false;
@@ -8,6 +11,7 @@ module BABYLON.GUI {
         private _doNotTrackManualChanges = false;
         private _tempMeasureStore = Measure.Empty();
 
+        /** Gets or sets a boolean indicating if the stack panel is vertical or horizontal*/
         public get isVertical(): boolean {
             return this._isVertical;
         }
@@ -21,6 +25,7 @@ module BABYLON.GUI {
             this._markAsDirty();
         }
        
+        /** Gets or sets panel width */
         public set width(value: string | number ) {
             if (!this._doNotTrackManualChanges) {
                 this._manualWidth = true;
@@ -39,6 +44,7 @@ module BABYLON.GUI {
             return this._width.toString(this._host);
         }        
 
+        /** Gets or sets panel height */
         public set height(value: string | number ) {
             if (!this._doNotTrackManualChanges) {
                 this._manualHeight = true;
@@ -57,6 +63,10 @@ module BABYLON.GUI {
             return this._height.toString(this._host);
         }
     
+        /**
+         * Creates a new StackPanel
+         * @param name defines control name
+         */
         constructor(public name?: string) {
             super(name);
         }

+ 3 - 0
gui/src/2D/controls/textBlock.ts

@@ -1,6 +1,9 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to create text block control
+     */
     export class TextBlock extends Control {
         private _text = "";
         private _textWrapping = false;

+ 48 - 0
gui/src/2D/controls/virtualKeyboard.ts

@@ -2,34 +2,60 @@
 
 module BABYLON.GUI {
 
+    /**
+     * Class used to store key control properties
+     */
     export class KeyPropertySet {
+        /** Width */
         width?: string;
+        /** Height */
         height?: string;
+        /** Left padding */
         paddingLeft?: string;
+        /** Right padding */
         paddingRight?: string;
+        /** Top padding */
         paddingTop?: string;
+        /** Bottom padding */
         paddingBottom?: string;
+        /** Foreground color */
         color?: string;
+        /** Background color */
         background?: string;
     }
 
+    /**
+     * Class used to create virtual keyboard
+     */
     export class VirtualKeyboard extends StackPanel {
+        /** Observable raised when a key is pressed */
         public onKeyPressObservable = new Observable<string>();
 
+        /** Gets or sets default key button width */
         public defaultButtonWidth = "40px";
+        /** Gets or sets default key button height */
         public defaultButtonHeight = "40px";
 
+        /** Gets or sets default key button left padding */
         public defaultButtonPaddingLeft = "2px";
+        /** Gets or sets default key button right padding */
         public defaultButtonPaddingRight = "2px";
+        /** Gets or sets default key button top padding */
         public defaultButtonPaddingTop = "2px";
+        /** Gets or sets default key button bottom padding */
         public defaultButtonPaddingBottom = "2px";
 
+        /** Gets or sets default key button foreground color */
         public defaultButtonColor = "#DDD";
+        /** Gets or sets default key button background color */
         public defaultButtonBackground = "#070707";
 
+        /** Gets or sets shift button foreground color */
         public shiftButtonColor = "#7799FF";
+        /** Gets or sets shift button thickness*/
         public selectedShiftThickness = 1;
 
+        /** Gets shift key state */
         public shiftState = 0;
 
         protected _getTypeName(): string {
@@ -63,6 +89,11 @@ module BABYLON.GUI {
             return button;
         }
 
+        /**
+         * Adds a new row of keys
+         * @param keys defines the list of keys to add
+         * @param propertySets defines the associated property sets
+         */
         public addKeysRow(keys: Array<string>, propertySets?: Array<KeyPropertySet>): void {
             let panel = new StackPanel();
             panel.isVertical = false;
@@ -81,6 +112,10 @@ module BABYLON.GUI {
             this.addControl(panel);
         }
 
+        /**
+         * Set the shift key to a specific state
+         * @param shiftState defines the new shift state
+         */
         public applyShiftState(shiftState: number): void {
             if (!this.children) {
                 return;
@@ -117,10 +152,15 @@ module BABYLON.GUI {
         private _onBlurObserver: Nullable<Observer<InputText>>;
         private _onKeyPressObserver: Nullable<Observer<string>>;
 
+        /** Gets the input text control attached with the keyboard */
         public get connectedInputText(): Nullable<InputText> {
             return this._connectedInputText;
         }
 
+        /**
+         * Connects the keyboard with an input text control
+         * @param input defines the target control
+         */
         public connect(input: InputText): void {
             this.isVisible = false;
             this._connectedInputText = input;
@@ -162,6 +202,9 @@ module BABYLON.GUI {
             });
         }
 
+        /**
+         * Disconnects the keyboard from an input text control
+         */
         public disconnect(): void {
             if (!this._connectedInputText) {
                 return;
@@ -175,6 +218,11 @@ module BABYLON.GUI {
         }
 
         // Statics
+
+        /**
+         * Creates a new keyboard using a default layout
+         * @returns a new VirtualKeyboard
+         */
         public static CreateDefaultLayout(): VirtualKeyboard {
             let returnValue = new VirtualKeyboard();
 

+ 87 - 3
gui/src/2D/math2D.ts

@@ -1,19 +1,50 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
-    export class Vector2WithInfo extends Vector2 {        
-        public constructor(source: Vector2, public buttonIndex: number = 0) {
+    /**
+     * Class used to transport Vector2 information for pointer events
+     */    
+    export class Vector2WithInfo extends Vector2 {    
+        /**
+         * Creates a new Vector2WithInfo
+         * @param source defines the vector2 data to transport
+         * @param buttonIndex defines the current mouse button index
+         */    
+        public constructor(source: Vector2, 
+            /** defines the current mouse button index */
+            public buttonIndex: number = 0) {
             super(source.x, source.y);
         }
     }
 
+    /** Class used to provide 2D matrix features */
     export class Matrix2D {
+        /** Gets the internal array of 6 floats used to store matrix data */
         public m = new Float32Array(6);
 
+        /**
+         * Creates a new matrix
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1) 
+         * @param m10 defines value for (1, 0) 
+         * @param m11 defines value for (1, 1) 
+         * @param m20 defines value for (2, 0) 
+         * @param m21 defines value for (2, 1) 
+         */
         constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) {
             this.fromValues(m00, m01, m10, m11, m20, m21);
         }
 
+        /**
+         * Fills the matrix from direct values
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         * @returns the current modified matrix
+         */
         public fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D {
             this.m[0] = m00; this.m[1] = m01; 
             this.m[2] = m10; this.m[3] = m11;
@@ -21,10 +52,19 @@ module BABYLON.GUI {
             return this;
         }
 
+        /** 
+         * Gets matrix determinant
+         * @returns the determinant
+         */
         public determinant(): number {
             return this.m[0] * this.m[3] - this.m[1] * this.m[2];
         }
 
+        /**
+         * Inverses the matrix and stores it in a target matrix
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
         public invertToRef(result: Matrix2D): Matrix2D {
             let l0 = this.m[0]; let l1 = this.m[1];
             let l2 = this.m[2]; let l3 = this.m[3];
@@ -50,6 +90,12 @@ module BABYLON.GUI {
             return this;
         }
 
+        /**
+         * Multiplies the current matrix with another one
+         * @param other defines the second operand
+         * @param result defines the target matrix 
+         * @returns the current matrix
+         */
         public multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D {
             let l0 = this.m[0];     let l1 = this.m[1];
             let l2 = this.m[2];     let l3 = this.m[3];
@@ -66,6 +112,13 @@ module BABYLON.GUI {
             return this;
         }
 
+        /**
+         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+         * @param x defines the x coordinate to transform
+         * @param y defines the x coordinate to transform 
+         * @param result defines the target vector2 
+         * @returns the current matrix
+         */
         public transformCoordinates(x: number, y: number, result: Vector2): Matrix2D {
             result.x = x * this.m[0] + y * this.m[2] + this.m[4];
             result.y = x * this.m[1] + y * this.m[3] + this.m[5];
@@ -74,18 +127,39 @@ module BABYLON.GUI {
         }
 
         // Statics
+        /**
+         * Creates an identity matrix
+         * @returns a new matrix
+         */
         public static Identity(): Matrix2D {
             return new Matrix2D(1, 0, 0, 1, 0, 0);
         }
 
+        /**
+         * Creates a translation matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the translation
+         * @param y defines the y coordinate of the translation 
+         * @param result defines the target matrix
+         */
         public static TranslationToRef(x: number, y: number, result: Matrix2D): void {
             result.fromValues(1, 0, 0, 1, x, y);
         }
 
+        /**
+         * Creates a scaling matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the scaling
+         * @param y defines the y coordinate of the scaling 
+         * @param result defines the target matrix
+         */
         public static ScalingToRef(x: number, y: number, result: Matrix2D): void {
             result.fromValues(x, 0, 0, y,  0, 0);
         }
 
+        /**
+         * Creates a rotation matrix and stores it in a target matrix
+         * @param angle defines the rotation angle
+         * @param result defines the target matrix
+         */        
         public static RotationToRef(angle: number, result: Matrix2D): void {
             var s = Math.sin(angle);
             var c = Math.cos(angle);
@@ -101,6 +175,16 @@ module BABYLON.GUI {
         private static _TempCompose1 = Matrix2D.Identity();
         private static _TempCompose2 = Matrix2D.Identity();
 
+        /**
+         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix 
+         * @param tx defines the x coordinate of the translation
+         * @param ty defines the y coordinate of the translation 
+         * @param angle defines the rotation angle 
+         * @param scaleX defines the x coordinate of the scaling
+         * @param scaleY defines the y coordinate of the scaling 
+         * @param parentMatrix defines the parent matrix to multiply by (can be null)
+         * @param result defines the target matrix 
+         */
         public static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>,  result: Matrix2D): void {
             Matrix2D.TranslationToRef(tx, ty, Matrix2D._TempPreTranslationMatrix);
 
@@ -120,4 +204,4 @@ module BABYLON.GUI {
             }
         }
     }    
-}
+}

+ 32 - 1
gui/src/2D/measure.ts

@@ -1,11 +1,33 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to store 2D control sizes
+     */
     export class Measure {
-        public constructor(public left: number, public top: number, public width: number, public height: number) {
+        /**
+         * Creates a new measure
+         * @param left defines left coordinate
+         * @param top defines top coordinate 
+         * @param width defines width dimension
+         * @param height defines height dimension
+         */
+        public constructor(
+            /** defines left coordinate */
+            public left: number, 
+            /** defines top coordinate  */
+            public top: number, 
+            /** defines width dimension  */
+            public width: number, 
+            /** defines height dimension */
+            public height: number) {
 
         }
 
+        /**
+         * Copy from another measure
+         * @param other defines the other measure to copy from
+         */
         public copyFrom(other: Measure): void {
             this.left = other.left;
             this.top = other.top;
@@ -13,6 +35,11 @@ module BABYLON.GUI {
             this.height = other.height;
         }
 
+        /**
+         * Check equality between this measure and another one
+         * @param other defines the other measures
+         * @returns true if both measures are equals
+         */
         public isEqualsTo(other: Measure): boolean {
 
             if (this.left !== other.left) {
@@ -34,6 +61,10 @@ module BABYLON.GUI {
             return true;
         }
 
+        /**
+         * Creates an empty measure
+         * @returns a new measure
+         */
         public static Empty(): Measure {
             return new Measure(0, 0, 0, 0);
         }

+ 18 - 0
gui/src/2D/multiLinePoint.ts

@@ -2,6 +2,10 @@
 
 module BABYLON.GUI {
 
+    /**
+     * Class used to store a point for a MultiLine object.
+     * The point can be pure 2D coordinates, a mesh or a control
+     */
     export class MultiLinePoint {
 
         private _multiLine: MultiLine;
@@ -14,8 +18,13 @@ module BABYLON.GUI {
         private _controlObserver: Nullable< Observer<Control> >;
         private _meshObserver: Nullable< Observer<Camera> >;
 
+        /** @hidden */
         public _point: Vector2;
 
+        /**
+         * Creates a new MultiLinePoint
+         * @param multiLine defines the source MultiLine object
+         */
         constructor(multiLine: MultiLine) {
             this._multiLine = multiLine;
 
@@ -25,6 +34,7 @@ module BABYLON.GUI {
             this._point = new Vector2(0, 0);
         }
 
+        /** Gets or sets x coordinate */
         public get x(): string | number {
             return this._x.toString(this._multiLine._host);
         }
@@ -39,6 +49,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets y coordinate */
         public get y(): string | number {
             return this._y.toString(this._multiLine._host);
         }
@@ -53,6 +64,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Gets or sets the control associated with this point */
         public get control(): Nullable<Control> {
             return this._control;
         }
@@ -77,6 +89,7 @@ module BABYLON.GUI {
             this._multiLine._markAsDirty();
         }
 
+        /** Gets or sets the mesh associated with this point */
         public get mesh(): Nullable<AbstractMesh> {
             return this._mesh;
         }
@@ -99,6 +112,10 @@ module BABYLON.GUI {
             this._multiLine._markAsDirty();
         }
 
+        /** 
+         * Gets a translation vector
+         * @returns the translation vector
+         */
         public translate(): Vector2 {
             this._point = this._translatePoint();
 
@@ -122,6 +139,7 @@ module BABYLON.GUI {
             }
         }
 
+        /** Release associated resources */
         public dispose(): void {
             this.control = null;
             this.mesh = null;

+ 15 - 0
gui/src/2D/style.ts

@@ -8,6 +8,7 @@ module BABYLON.GUI {
     export class Style implements BABYLON.IDisposable {
         private _fontFamily = "Arial";
         private _fontStyle = "";       
+        private _fontWeight = "";     
         /** @hidden */ 
         public _host: AdvancedDynamicTexture;
         /** @hidden */
@@ -75,6 +76,20 @@ module BABYLON.GUI {
             this.onChangedObservable.notifyObservers(this);
         }
 
+        /** Gets or sets font weight */
+        public get fontWeight(): string {
+            return this._fontWeight;
+        }
+
+        public set fontWeight(value: string) {
+            if (this._fontWeight === value) {
+                return;
+            }
+
+            this._fontWeight = value;            
+            this.onChangedObservable.notifyObservers(this);
+        }          
+
         /** Dispose all associated resources */
         public dispose() {
             this.onChangedObservable.clear();

+ 44 - 1
gui/src/2D/valueAndUnit.ts

@@ -1,26 +1,52 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to specific a value and its associated unit
+     */
     export class ValueAndUnit {
         private _value = 1;
+        /**
+         * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
+         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         */
         public ignoreAdaptiveScaling = false;
 
-        public constructor(value: number, public unit = ValueAndUnit.UNITMODE_PIXEL, public negativeValueAllowed = true) {
+        /**
+         * Creates a new ValueAndUnit
+         * @param value defines the value to store
+         * @param unit defines the unit to store
+         * @param negativeValueAllowed defines a boolean indicating if the value can be negative
+         */
+        public constructor(value: number, 
+            /** defines the unit to store */
+            public unit = ValueAndUnit.UNITMODE_PIXEL, 
+            /** defines a boolean indicating if the value can be negative */
+            public negativeValueAllowed = true) {
             this._value = value;
         }
 
+        /** Gets a boolean indicating if the value is a percentage */
         public get isPercentage(): boolean {
             return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
         }
 
+        /** Gets a boolean indicating if the value is store as pixel */
         public get isPixel(): boolean {
             return this.unit === ValueAndUnit.UNITMODE_PIXEL;
         }
 
+        /** Gets direct internal value */
         public get internalValue(): number {
             return this._value;
         }
 
+        /**
+         * Gets value as pixel
+         * @param host defines the root host
+         * @param refValue defines the reference value for percentages
+         * @returns the value as pixel
+         */
         public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
             if (this.isPixel) {
                 return this.getValue(host);
@@ -29,6 +55,11 @@ module BABYLON.GUI {
             return this.getValue(host) * refValue;
         }
 
+        /**
+         * Gets the value accordingly to its unit
+         * @param host  defines the root host
+         * @returns the value
+         */
         public getValue(host: AdvancedDynamicTexture): number {
             if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
                 var width: number = 0;
@@ -57,6 +88,11 @@ module BABYLON.GUI {
             return this._value;
         }
 
+        /**
+         * Gets a string representation of the value
+         * @param host defines the root host
+         * @returns a string
+         */
         public toString(host: AdvancedDynamicTexture): string {
             switch (this.unit) {
                 case ValueAndUnit.UNITMODE_PERCENTAGE:
@@ -68,6 +104,11 @@ module BABYLON.GUI {
             return this.unit.toString();
         }
 
+        /**
+         * Store a value parsed from a string
+         * @param source defines the source string
+         * @returns true if the value was successfully parsed
+         */
         public fromString(source: string | number ): boolean {
             var match = ValueAndUnit._Regex.exec(source.toString());
 
@@ -111,10 +152,12 @@ module BABYLON.GUI {
         private static _UNITMODE_PERCENTAGE = 0;
         private static _UNITMODE_PIXEL = 1;
 
+        /** UNITMODE_PERCENTAGE */
         public static get UNITMODE_PERCENTAGE(): number {
             return ValueAndUnit._UNITMODE_PERCENTAGE;
         }
 
+        /** UNITMODE_PIXEL */
         public static get UNITMODE_PIXEL(): number {
             return ValueAndUnit._UNITMODE_PIXEL;
         }   

+ 67 - 4
gui/src/3D/controls/button3D.ts

@@ -7,8 +7,54 @@ module BABYLON.GUI {
     export class Button3D extends Control3D {
         /** @hidden */
         protected _currentMaterial: Material;
-        private _facadeTexture: AdvancedDynamicTexture;
+        private _facadeTexture: Nullable<AdvancedDynamicTexture>;
         private _content: Control;
+        private _contentResolution = 512;
+        private _contentScaleRatio = 2;
+
+        /**
+         * Gets or sets the texture resolution used to render content (512 by default)
+         */
+        public get contentResolution(): int {
+            return this._contentResolution;
+        }
+
+        public set contentResolution(value: int) {
+            if (this._contentResolution === value) {
+                return;
+            }
+
+            this._contentResolution = value;
+            this._resetContent();
+        }
+
+        /**
+         * Gets or sets the texture scale ratio used to render content (2 by default)
+         */
+        public get contentScaleRatio(): number {
+            return this._contentScaleRatio;
+        }
+
+        public set contentScaleRatio(value: number) {
+            if (this._contentScaleRatio === value) {
+                return;
+            }
+
+            this._contentScaleRatio = value;
+            this._resetContent();
+        }   
+        
+        protected _disposeFacadeTexture() {
+            if (this._facadeTexture) {
+                this._facadeTexture.dispose();
+                this._facadeTexture = null;
+            }
+        }
+
+        protected _resetContent() {
+            this._disposeFacadeTexture();
+            this.content = this._content;
+        }
 
         /**
          * Creates a new button
@@ -55,14 +101,16 @@ module BABYLON.GUI {
         }
 
         public set content(value: Control) {
+            this._content = value;
+
             if (!this._host || !this._host.utilityLayer) {
                 return;
             }
 
             if (!this._facadeTexture) {
-                this._facadeTexture = new BABYLON.GUI.AdvancedDynamicTexture("Facade", 512, 512, this._host.utilityLayer.utilityLayerScene, true, BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
-                this._facadeTexture.rootContainer.scaleX = 2;
-                this._facadeTexture.rootContainer.scaleY = 2;
+                this._facadeTexture = new BABYLON.GUI.AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
+                this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
+                this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
                 this._facadeTexture.premulAlpha = true;
             }
             
@@ -109,6 +157,21 @@ module BABYLON.GUI {
 
             mesh.material = material;
             this._currentMaterial = material;
+
+            this._resetContent();
+        }
+
+        /**
+         * Releases all associated resources
+         */
+        public dispose() {
+            super.dispose();
+
+            this._disposeFacadeTexture();
+
+            if (this._currentMaterial) {
+                this._currentMaterial.dispose();
+            }
         }
     }
 }

+ 2 - 1
gui/src/3D/controls/container3D.ts

@@ -68,7 +68,7 @@ module BABYLON.GUI {
         }
 
         /**
-         * Removes the control from the children of this control
+         * Removes a control from the children of this control
          * @param control defines the control to remove
          * @returns the current container
          */
@@ -79,6 +79,7 @@ module BABYLON.GUI {
                 this._children.splice(index, 1);
 
                 control.parent = null;
+                control._disposeNode();
             }
 
             return this;

+ 24 - 16
gui/src/3D/controls/control3D.ts

@@ -9,13 +9,13 @@ module BABYLON.GUI {
         public _host: GUI3DManager;
         private _node: Nullable<TransformNode>;
         private _downCount = 0;
-        private _enterCount = 0;
+        private _enterCount = -1;
         private _downPointerIds:{[id:number] : boolean} = {};
         private _isVisible = true;
-
-        /** Gets or sets the control position */
+    
+        /** Gets or sets the control position  in world space */
         public position = new Vector3(0, 0, 0);
-        /** Gets or sets the control scaling */
+        /** Gets or sets the control scaling  in world space */
         public scaling = new Vector3(1, 1, 1);
 
         /** Callback used to start pointer enter animation */
@@ -28,12 +28,12 @@ module BABYLON.GUI {
         public pointerUpAnimation: () => void;
 
         /**
-        * An event triggered when the pointer move over the control.
+        * An event triggered when the pointer move over the control
         */
         public onPointerMoveObservable = new Observable<Vector3>();
 
         /**
-         * An event triggered when the pointer move out of the control.
+         * An event triggered when the pointer move out of the control
          */
         public onPointerOutObservable = new Observable<Control3D>();
 
@@ -43,12 +43,12 @@ module BABYLON.GUI {
         public onPointerDownObservable = new Observable<Vector3WithInfo>();
 
         /**
-         * An event triggered when pointer up
+         * An event triggered when pointer is up
          */
         public onPointerUpObservable = new Observable<Vector3WithInfo>();
 
         /**
-         * An event triggered when a control is clicked on
+         * An event triggered when a control is clicked on (with a mouse)
          */
         public onPointerClickObservable = new Observable<Vector3WithInfo>();
 
@@ -175,7 +175,7 @@ module BABYLON.GUI {
         }
 
         /**
-         * Gets the mesh used to render this control
+         * Gets the transform node used by this control
          */
         public get node(): Nullable<TransformNode> {
             return this._node;
@@ -244,7 +244,6 @@ module BABYLON.GUI {
             mesh.material = null;
         }
 
-
         // Pointers
 
         /** @hidden */
@@ -254,10 +253,14 @@ module BABYLON.GUI {
 
         /** @hidden */
         public _onPointerEnter(target: Control3D): boolean {
-            if (this._enterCount !== 0) {
+            if (this._enterCount > 0) {
                 return false;
             }
 
+            if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
+                this._enterCount = 0;
+            }
+
             this._enterCount++;
 
             this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
@@ -305,7 +308,7 @@ module BABYLON.GUI {
 
             delete this._downPointerIds[pointerId];
 
-			if (notifyClick && this._enterCount > 0) {
+			if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
 				this.onPointerClickObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 			}
 			this.onPointerUpObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);            
@@ -362,6 +365,14 @@ module BABYLON.GUI {
             return false;
         }        
 
+        /** @hidden */
+        public _disposeNode(): void {
+            if (this._node) {
+                this._node.dispose();
+                this._node = null;
+            }
+        }
+
         /**
          * Releases all associated resources
          */
@@ -373,10 +384,7 @@ module BABYLON.GUI {
             this.onPointerUpObservable.clear();
             this.onPointerClickObservable.clear();
 
-            if (this._node) {
-                this._node.dispose(false, true);
-                this._node = null;
-            }
+            this._disposeNode();
 
             // Behaviors
             for (var behavior of this._behaviors) {

+ 135 - 16
gui/src/3D/controls/holographicButton.ts

@@ -8,10 +8,13 @@ module BABYLON.GUI {
         private _backPlate: Mesh;
         private _textPlate: Mesh;
         private _frontPlate: Mesh;
-        private _backFluentMaterial: FluentMaterial;
-        private _frontFluentMaterial: FluentMaterial;
         private _text: string;
-        // private _imageUrl: string;
+        private _imageUrl: string;
+        private _shareMaterials = true;
+        private _frontMaterial: FluentMaterial;
+        private _backMaterial: FluentMaterial;
+        private _plateMaterial: StandardMaterial;
+        private _pickedPointObserver: Nullable<Observer<Nullable<Vector3>>>;
 
         /**
          * Gets or sets text for the button
@@ -30,14 +33,59 @@ module BABYLON.GUI {
         }
 
         /**
+         * Gets or sets the image url for the button
+         */
+        public get imageUrl(): string {
+            return this._imageUrl;
+        }
+
+        public set imageUrl(value: string) {
+            if (this._imageUrl === value) {
+                return;
+            }
+
+            this._imageUrl = value;
+            this._rebuildContent();
+        }        
+
+        /**
+         * Gets the back material used by this button
+         */
+        public get backMaterial(): FluentMaterial {
+            return this._backMaterial;
+        }
+
+        /**
+         * Gets the front material used by this button
+         */
+        public get frontMaterial(): FluentMaterial {
+            return this._frontMaterial;
+        }       
+        
+        /**
+         * Gets the plate material used by this button
+         */
+        public get plateMaterial(): StandardMaterial {
+            return this._plateMaterial;
+        }          
+
+        /**
+         * Gets a boolean indicating if this button shares its material with other HolographicButtons
+         */
+        public get shareMaterials(): boolean {
+            return this._shareMaterials;
+        }
+
+        /**
          * Creates a new button
          * @param name defines the control name
          */
-        constructor(name?: string) {
+        constructor(name?: string, shareMaterials = true) {
             super(name);
 
-            // Default animations
+            this._shareMaterials = shareMaterials;
 
+            // Default animations
             this.pointerEnterAnimation = () => {
                 if (!this.mesh) {
                     return;
@@ -58,9 +106,21 @@ module BABYLON.GUI {
         }        
 
         private _rebuildContent(): void {
+            this._disposeFacadeTexture();
+
             let panel = new StackPanel();
             panel.isVertical = true;
 
+            if (this._imageUrl) {
+                let image = new BABYLON.GUI.Image();
+                image.source = this._imageUrl;
+                image.paddingTop = "40px";
+                image.height = "180px";
+                image.width = "100px";
+                image.paddingBottom = "40px";
+                panel.addControl(image);                
+            }
+
             if (this._text) {
                 let text = new BABYLON.GUI.TextBlock();
                 text.text = this._text;
@@ -103,22 +163,81 @@ module BABYLON.GUI {
         }
 
         protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
-            (<any>this._currentMaterial).emissiveTexture = facadeTexture;
-            (<any>this._currentMaterial).opacityTexture = facadeTexture;
-        }        
+            this._plateMaterial.emissiveTexture = facadeTexture;
+            this._plateMaterial.opacityTexture = facadeTexture;
+        }   
+        
+        private _createBackMaterial(mesh: Mesh) {
+            this._backMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
+            this._backMaterial.renderHoverLight = true;
+            this._pickedPointObserver = this._host.onPickedPointChangedObservable.add(pickedPoint => {
+                if (pickedPoint) {
+                    this._backMaterial.hoverPosition = pickedPoint;
+                    this._backMaterial.hoverColor.a = 1.0;
+                } else {
+                    this._backMaterial.hoverColor.a = 0;
+                }
+            });
+        }
+
+        private _createFrontMaterial(mesh: Mesh) {
+            this._frontMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
+            this._frontMaterial.innerGlowColorIntensity = 0; // No inner glow
+            this._frontMaterial.alpha = 0.5; // Additive
+            this._frontMaterial.renderBorders = true;
+        }     
+        
+        private _createPlateMaterial(mesh: Mesh) {
+            this._plateMaterial = new StandardMaterial(this.name + "Plate Material", mesh.getScene());
+            this._plateMaterial.specularColor = Color3.Black();
+        }
 
         protected _affectMaterial(mesh: Mesh) {
-            this._backFluentMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
-            mesh.material = this._backFluentMaterial;
+            // Back
+            if (this._shareMaterials) {
+                if (!this._host._sharedMaterials["backFluentMaterial"]) {
+                    this._createBackMaterial(mesh);
+                    this._host._sharedMaterials["backFluentMaterial"] =  this._backMaterial;
+                } else {
+                    this._backMaterial = this._host._sharedMaterials["backFluentMaterial"] as FluentMaterial;
+                }
 
-            this._frontFluentMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
-            this._frontPlate.material = this._frontFluentMaterial;
-            this._frontFluentMaterial.innerGlowColorIntensity = 0; // No inner glow
-            this._frontFluentMaterial.alpha = 0.5; // Additive
-            this._frontFluentMaterial.renderBorders = true;
+                // Front
+                if (!this._host._sharedMaterials["frontFluentMaterial"]) {
+                    this._createFrontMaterial(mesh);
+                    this._host._sharedMaterials["frontFluentMaterial"] = this._frontMaterial;                
+                } else {
+                    this._frontMaterial = this._host._sharedMaterials["frontFluentMaterial"] as FluentMaterial;
+                }  
+            } else {
+                this._createBackMaterial(mesh);
+                this._createFrontMaterial(mesh);
+            }
+
+            this._createPlateMaterial(mesh);
+            this._backPlate.material =  this._backMaterial;
+            this._frontPlate.material = this._frontMaterial;
+            this._textPlate.material = this._plateMaterial;
 
-            super._affectMaterial(this._textPlate);
             this._rebuildContent();
         }
+
+        /**
+         * Releases all associated resources
+         */
+        public dispose() {
+            super.dispose(); // will dispose main mesh ie. back plate
+            
+            if (!this.shareMaterials) {
+                this._backMaterial.dispose();
+                this._frontMaterial.dispose();
+                this._plateMaterial.dispose();
+
+                if (this._pickedPointObserver) {
+                    this._host.onPickedPointChangedObservable.remove(this._pickedPointObserver);
+                    this._pickedPointObserver = null;
+                }
+            }
+        }        
     }
 }

+ 3 - 1
gui/src/3D/controls/stackPanel3D.ts

@@ -55,8 +55,10 @@ module BABYLON.GUI {
 
                 controlCount++;
                 child.mesh.computeWorldMatrix(true);
+                child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+
                 let boundingBox = child.mesh.getBoundingInfo().boundingBox;
-                let extendSize = Vector3.TransformNormal(boundingBox.extendSizeWorld, currentInverseWorld);
+                let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
                 extendSizes.push(extendSize);
 
                 if (this._isVertical) {

+ 36 - 2
gui/src/3D/gui3DManager.ts

@@ -3,6 +3,7 @@
 module BABYLON.GUI {
     /**
      * Class used to manage 3D user interface
+     * @see http://doc.babylonjs.com/how_to/gui3d
      */
     export class GUI3DManager implements BABYLON.IDisposable {
         private _scene: Scene;
@@ -10,17 +11,28 @@ module BABYLON.GUI {
         private _utilityLayer: Nullable<UtilityLayerRenderer>;
         private _rootContainer: Container3D;
         private _pointerObserver: Nullable<Observer<PointerInfoPre>>;
+        /** @hidden */
         public _lastPickedControl: Control3D;
         /** @hidden */
         public _lastControlOver: {[pointerId:number]: Control3D} = {};
         /** @hidden */
         public _lastControlDown: {[pointerId:number]: Control3D} = {};      
 
+        /**
+         * Observable raised when the point picked by the pointer events changed
+         */
+        public onPickedPointChangedObservable = new Observable<Nullable<Vector3>>();
+
+        // Shared resources
+        /** @hidden */
+        public _sharedMaterials: {[key:string]: Material} = {};     
+
         /** Gets the hosting scene */
         public get scene(): Scene {
             return this._scene;
         }
 
+        /** Gets associated utility layer */
         public get utilityLayer(): Nullable<UtilityLayerRenderer> {
             return this._utilityLayer;
         }
@@ -45,6 +57,11 @@ module BABYLON.GUI {
             
             // Events
             this._pointerObserver = this._scene.onPrePointerObservable.add((pi, state) => {
+
+                if (pi.skipOnPointerObservable) {
+                    return;
+                }
+
                 let pointerEvent = <PointerEvent>(pi.event);
                 if (this._scene.isPointerCaptured(pointerEvent.pointerId)) {
                     return;
@@ -93,11 +110,16 @@ module BABYLON.GUI {
                         this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
                         delete this._lastControlDown[pointerEvent.pointerId];
                     }
-                }                
+                }        
+                
+                this.onPickedPointChangedObservable.notifyObservers(null);
                 return false;
             }
 
             let control = <Control3D>(pickingInfo.pickedMesh!.metadata);
+            if (pickingInfo.pickedPoint) {
+                this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
+            }
 
             if (!control._processObservables(type, pickingInfo.pickedPoint!, pointerId, buttonIndex)) {
 
@@ -147,7 +169,7 @@ module BABYLON.GUI {
         }
 
         /**
-         * Removes the control from the root child list
+         * Removes a control from the root child list
          * @param control defines the control to remove
          * @returns the current container
          */
@@ -162,6 +184,18 @@ module BABYLON.GUI {
         public dispose() {
             this._rootContainer.dispose();
 
+            for (var materialName in this._sharedMaterials) {
+                if (!this._sharedMaterials.hasOwnProperty(materialName)) {
+                    continue;
+                }
+
+                this._sharedMaterials[materialName].dispose();
+            }
+
+            this._sharedMaterials = {};
+
+            this.onPickedPointChangedObservable.clear();
+
             if (this._scene) {
                 if (this._pointerObserver) {
                     this._scene.onPrePointerObservable.remove(this._pointerObserver);

+ 40 - 4
gui/src/3D/materials/fluentMaterial.ts

@@ -6,6 +6,7 @@ module BABYLON.GUI {
     export class FluentMaterialDefines extends MaterialDefines {
         public INNERGLOW = false;
         public BORDER = false;
+        public HOVERLIGHT = false;
     
         constructor() {
             super();
@@ -60,13 +61,38 @@ module BABYLON.GUI {
          * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
          */
         @serialize()
-        public edgeSmoothingValue = 0.02;       
+        public edgeSmoothingValue = 0.02;
         
         /**
          * Gets or sets the minimum value that can be applied to border width (default is 0.1)
          */
         @serialize()
-        public borderMinValue = 0.1;        
+        public borderMinValue = 0.1;      
+        
+        /**
+         * Gets or sets a boolean indicating if hover light must be rendered (default is false)
+         */
+        @serialize()
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public renderHoverLight = false;         
+        
+        /**
+         * Gets or sets the radius used to render the hover light (default is 0.15)
+         */
+        @serialize()
+        public hoverRadius = 1.0;            
+        
+        /**
+         * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
+         */
+        @serializeAsColor4()
+        public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);           
+        
+        /**
+         * Gets or sets the hover light position in world space (default is Vector3.Zero())
+         */
+        @serializeAsVector3()
+        public hoverPosition = Vector3.Zero();             
         
         /**
          * Creates a new Fluent material
@@ -111,6 +137,7 @@ module BABYLON.GUI {
             if (defines._areTexturesDirty) {
                 defines.INNERGLOW = this.innerGlowColorIntensity > 0;
                 defines.BORDER = this.renderBorders;
+                defines.HOVERLIGHT = this.renderHoverLight;
             }
 
             var engine = scene.getEngine();
@@ -126,7 +153,9 @@ module BABYLON.GUI {
 
                 var shaderName = "fluent";
 
-                var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue"];
+                var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
+                                "hoverColor", "hoverPosition", "hoverRadius"
+                ];
 
                 var samplers = new Array<String>();
                 var uniformBuffers = new Array<string>();
@@ -196,7 +225,14 @@ module BABYLON.GUI {
                     this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
                     this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
 
-                    this._activeEffect.setVector3("scaleFactor", mesh.getBoundingInfo().boundingBox.extendSizeWorld);
+                    mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
+                    this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
+                }
+
+                if (defines.HOVERLIGHT) {
+                    this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
+                    this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
+                    this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
                 }
             }
 

+ 14 - 1
gui/src/3D/materials/shaders/fluent.fragment.fx

@@ -12,7 +12,14 @@ uniform vec4 innerGlowColor;
 varying vec2 scaleInfo;
 uniform float edgeSmoothingValue;
 uniform float borderMinValue;
+#endif
+
+#ifdef HOVERLIGHT
+varying vec3 worldPosition;
 
+uniform vec3 hoverPosition;
+uniform vec4 hoverColor;
+uniform float hoverRadius;
 #endif
 
 void main(void) {
@@ -20,10 +27,16 @@ void main(void) {
 	vec3 albedo = albedoColor.rgb;
 	float alpha = albedoColor.a;
 
+#ifdef HOVERLIGHT
+	float pointToHover = (1.0 - clamp(length(hoverPosition - worldPosition) / hoverRadius, 0., 1.)) * hoverColor.a;
+	albedo = clamp(albedo + hoverColor.rgb * pointToHover, 0., 1.);
+#else
+	float pointToHover = 1.0;
+#endif
+
 #ifdef BORDER	
 	float borderPower = 10.0;
 	float inverseBorderPower = 1.0 / borderPower;
-	float pointToHover = 1.0;
 	vec3 borderColor = albedo * borderPower;
 
 	vec2 distanceToEdge;

+ 11 - 1
gui/src/3D/materials/shaders/fluent.vertex.fx

@@ -17,6 +17,10 @@ uniform float borderWidth;
 uniform vec3 scaleFactor;
 #endif
 
+#ifdef HOVERLIGHT
+varying vec3 worldPosition;
+#endif
+
 void main(void) {
 	vUV = uv;
 
@@ -70,5 +74,11 @@ void main(void) {
 	}	
 #endif		
 
-	gl_Position = viewProjection * world * vec4(position, 1.0);
+	vec4 worldPos = world * vec4(position, 1.0);
+
+#ifdef HOVERLIGHT
+	worldPosition = worldPos.xyz;
+#endif
+
+	gl_Position = viewProjection * worldPos;
 }

+ 11 - 1
gui/src/3D/vector3WithInfo.ts

@@ -1,8 +1,18 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GUI {
+    /**
+     * Class used to transport Vector3 information for pointer events
+     */
     export class Vector3WithInfo extends Vector3 {        
-        public constructor(source: Vector3, public buttonIndex: number = 0) {
+        /**
+         * Creates a new Vector3WithInfo
+         * @param source defines the vector3 data to transport
+         * @param buttonIndex defines the current mouse button index
+         */
+        public constructor(source: Vector3, 
+            /** defines the current mouse button index */
+            public buttonIndex: number = 0) {
             super(source.x, source.y, source.z);
         }
     }

+ 0 - 0
inspector/sass/_detailPanel.scss


Some files were not shown because too many files changed in this diff