David Catuhe 7 years ago
parent
commit
1607cfa7ae
33 changed files with 24639 additions and 23216 deletions
  1. 11335 11222
      Playground/babylon.d.txt
  2. 11486 11479
      dist/preview release/babylon.d.ts
  3. 13 12
      dist/preview release/babylon.js
  4. 304 3
      dist/preview release/babylon.max.js
  5. 304 3
      dist/preview release/babylon.no-module.max.js
  6. 13 12
      dist/preview release/babylon.worker.js
  7. 306 5
      dist/preview release/es6.js
  8. 1 1
      dist/preview release/gui/babylon.gui.d.ts
  9. 15 9
      dist/preview release/gui/babylon.gui.js
  10. 5 5
      dist/preview release/gui/babylon.gui.min.js
  11. 1 1
      dist/preview release/gui/babylon.gui.module.d.ts
  12. 1 0
      dist/preview release/inspector/babylon.inspector.d.ts
  13. 14 3
      dist/preview release/inspector/babylon.inspector.js
  14. 2 2
      dist/preview release/inspector/babylon.inspector.min.js
  15. 4 2
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  16. 3 3
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  17. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  18. 36 30
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  19. 114 98
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  20. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  21. 36 30
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  22. 117 99
      dist/preview release/loaders/babylon.glTFFileLoader.js
  23. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  24. 36 30
      dist/preview release/loaders/babylonjs.loaders.d.ts
  25. 117 99
      dist/preview release/loaders/babylonjs.loaders.js
  26. 4 4
      dist/preview release/loaders/babylonjs.loaders.min.js
  27. 36 30
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  28. 1 1
      dist/preview release/materialsLibrary/babylon.mixMaterial.js
  29. 1 1
      dist/preview release/materialsLibrary/babylon.mixMaterial.min.js
  30. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js
  31. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  32. 21 20
      dist/preview release/viewer/babylon.viewer.js
  33. 304 3
      dist/preview release/viewer/babylon.viewer.max.js

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


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


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


+ 304 - 3
dist/preview release/babylon.max.js

@@ -19252,6 +19252,9 @@ var BABYLON;
                     this._updateNonUniformScalingState(false);
                 }
             }
+            else {
+                this._updateNonUniformScalingState(false);
+            }
             this._afterComputeWorldMatrix();
             // Absolute position
             this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
@@ -36605,6 +36608,9 @@ var BABYLON;
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices, null, updatable);
             }
+            else {
+                meshOrGeometry.setIndices([], null);
+            }
             return this;
         };
         VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
@@ -65741,6 +65747,13 @@ var BABYLON;
             this.forceFullscreenViewport = true;
             /**
             * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+        *
+        * | Value | Type                                | Description |
+            * | ----- | ----------------------------------- | ----------- |
+            * | 1     | SCALEMODE_FLOOR                     | [engine.scalemode_floor](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |
+            * | 2     | SCALEMODE_NEAREST                   | [engine.scalemode_nearest](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |
+            * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |
+        *
             */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
             /**
@@ -86920,6 +86933,7 @@ var BABYLON;
             this._sceneDisposeObserver = this.originalScene.onDisposeObservable.add(function () {
                 _this.dispose();
             });
+            this._updateCamera();
         }
         /**
          * Renders the utility layers scene on top of the original scene
@@ -86963,10 +86977,11 @@ var BABYLON;
         function Gizmo(/** The utility layer the gizmo will be added to */ gizmoLayer) {
             var _this = this;
             this.gizmoLayer = gizmoLayer;
+            this._interactionsEnabled = true;
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode", gizmoLayer.utilityLayerScene);
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
                 if (_this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
-                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 5;
+                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 3;
                     _this._rootMesh.scaling.set(dist, dist, dist);
                 }
                 if (_this.attachedMesh) {
@@ -86974,6 +86989,22 @@ var BABYLON;
                 }
             });
         }
+        Gizmo.prototype._onInteractionsEnabledChanged = function (value) {
+        };
+        Object.defineProperty(Gizmo.prototype, "interactionsEnabled", {
+            get: function () {
+                return this._interactionsEnabled;
+            },
+            /**
+             * If interactions are enabled with this gizmo. (eg. dragging/rotation)
+             */
+            set: function (value) {
+                this._interactionsEnabled = value;
+                this._onInteractionsEnabledChanged(value);
+            },
+            enumerable: true,
+            configurable: true
+        });
         /**
          * Disposes of the gizmo
          */
@@ -87029,12 +87060,18 @@ var BABYLON;
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
                 if (_this.attachedMesh) {
                     _this.attachedMesh.position.addInPlace(event.delta);
                 }
             });
             return _this;
         }
+        AxisDragGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87053,6 +87090,162 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
+     * Single axis scale gizmo
+     */
+    var AxisScaleGizmo = /** @class */ (function (_super) {
+        __extends(AxisScaleGizmo, _super);
+        /**
+         * Creates an AxisScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param dragAxis The axis which the gizmo will be able to scale on
+         * @param color The color of the gizmo
+         */
+        function AxisScaleGizmo(gizmoLayer, dragAxis, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", { size: 1 }, gizmoLayer.utilityLayerScene);
+            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameter: 0.03, height: 0.2, tessellation: 96 }, gizmoLayer.utilityLayerScene);
+            _this._rootMesh.addChild(arrowMesh);
+            _this._rootMesh.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.1);
+            arrowMesh.material = coloredMaterial;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = coloredMaterial;
+            arrowTail.position.z += 0.2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh) {
+                    _this.attachedMesh.scaling.addInPlace(event.delta);
+                }
+            });
+            return _this;
+        }
+        AxisScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        AxisScaleGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return AxisScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.AxisScaleGizmo = AxisScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.axisScaleGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Single plane rotation gizmo
+     */
+    var PlaneRotationGizmo = /** @class */ (function (_super) {
+        __extends(PlaneRotationGizmo, _super);
+        /**
+         * Creates a PlaneRotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
+         * @param color The color of the gizmo
+         */
+        function PlaneRotationGizmo(gizmoLayer, planeNormal, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var rotationMesh = BABYLON.Mesh.CreateTorus("torus", 3, 0.3, 20, gizmoLayer.utilityLayerScene, false);
+            _this._rootMesh.addChild(rotationMesh);
+            // Position arrow pointing in its drag axis
+            rotationMesh.scaling.scaleInPlace(0.1);
+            rotationMesh.material = coloredMaterial;
+            rotationMesh.rotation.x = Math.PI / 2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(planeNormal));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragPlaneNormal: planeNormal, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            var lastDragPosition = null;
+            _this._dragBehavior.onDragStartObservable.add(function (e) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                lastDragPosition = e.dragPlanePoint;
+            });
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh && lastDragPosition) {
+                    if (!_this.attachedMesh.rotationQuaternion) {
+                        _this.attachedMesh.rotationQuaternion = new BABYLON.Quaternion();
+                    }
+                    // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)
+                    var newVector = event.dragPlanePoint.subtract(_this.attachedMesh.position).normalize();
+                    var originalVector = lastDragPosition.subtract(_this.attachedMesh.position).normalize();
+                    var cross = BABYLON.Vector3.Cross(newVector, originalVector);
+                    var dot = BABYLON.Vector3.Dot(newVector, originalVector);
+                    var angle = Math.atan2(cross.length(), dot);
+                    var up = planeNormal.clone();
+                    // Flip up vector depending on which side the camera is on
+                    if (gizmoLayer.utilityLayerScene.activeCamera) {
+                        var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(_this.attachedMesh.position);
+                        if (BABYLON.Vector3.Dot(camVec, up) > 0) {
+                            up.scaleInPlace(-1);
+                        }
+                    }
+                    var halfCircleSide = BABYLON.Vector3.Dot(up, cross) > 0.0;
+                    if (halfCircleSide)
+                        angle = -angle;
+                    // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
+                    var quaternionCoefficient = Math.sin(angle / 2);
+                    var amountToRotate = new BABYLON.Quaternion(up.x * quaternionCoefficient, up.y * quaternionCoefficient, up.z * quaternionCoefficient, Math.cos(angle / 2));
+                    // Rotate selected mesh quaternion over fixed axis
+                    amountToRotate.multiplyToRef(_this.attachedMesh.rotationQuaternion, _this.attachedMesh.rotationQuaternion);
+                    lastDragPosition = event.dragPlanePoint;
+                }
+            });
+            return _this;
+        }
+        PlaneRotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        PlaneRotationGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return PlaneRotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.PlaneRotationGizmo = PlaneRotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.planeRotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
      * Gizmo that enables dragging a mesh along 3 axis
      */
     var PositionGizmo = /** @class */ (function (_super) {
@@ -87077,6 +87270,11 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        PositionGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87092,6 +87290,102 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.positionGizmo.js.map
 
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables rotating a mesh along 3 axis
+     */
+    var RotationGizmo = /** @class */ (function (_super) {
+        __extends(RotationGizmo, _super);
+        /**
+         * Creates a RotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function RotationGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(RotationGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        RotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        RotationGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return RotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.RotationGizmo = RotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.rotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables scaling a mesh along 3 axis
+     */
+    var ScaleGizmo = /** @class */ (function (_super) {
+        __extends(ScaleGizmo, _super);
+        /**
+         * Creates a ScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function ScaleGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(ScaleGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        ScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        ScaleGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return ScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.ScaleGizmo = ScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.scaleGizmo.js.map
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -96637,6 +96931,10 @@ var BABYLON;
              *  Mesh with the position where the drag plane should be placed
              */
             this._dragPlaneParent = null;
+            /**
+             *  If the drag behavior will react to drag events
+             */
+            this.enabled = true;
             var optionCount = 0;
             if (options.dragAxis) {
                 optionCount++;
@@ -96690,6 +96988,9 @@ var BABYLON;
                 return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
             };
             this._pointerObserver = this.options.pointerObservableScene.onPrePointerObservable.add(function (pointerInfoPre, eventState) {
+                if (!_this.enabled) {
+                    return;
+                }
                 // Check if attached mesh is picked
                 var pickInfo = pointerInfoPre.ray ? _this._scene.pickWithRay(pointerInfoPre.ray, pickPredicate) : _this._scene.pick(_this._scene.pointerX, _this._scene.pointerY, pickPredicate);
                 if (pickInfo) {
@@ -96697,8 +96998,8 @@ var BABYLON;
                     if (!pickInfo.ray) {
                         pickInfo.ray = _this.options.pointerObservableScene.createPickingRay(_this._scene.pointerX, _this._scene.pointerY, BABYLON.Matrix.Identity(), _this._scene.activeCamera);
                     }
-                    if (pickInfo.hit) {
-                        eventState.skipNextObservers = true;
+                    if (pickInfo.hit && pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {
+                        pointerInfoPre.skipOnPointerObservable = true;
                     }
                 }
                 if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {

+ 304 - 3
dist/preview release/babylon.no-module.max.js

@@ -19219,6 +19219,9 @@ var BABYLON;
                     this._updateNonUniformScalingState(false);
                 }
             }
+            else {
+                this._updateNonUniformScalingState(false);
+            }
             this._afterComputeWorldMatrix();
             // Absolute position
             this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
@@ -36572,6 +36575,9 @@ var BABYLON;
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices, null, updatable);
             }
+            else {
+                meshOrGeometry.setIndices([], null);
+            }
             return this;
         };
         VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
@@ -65708,6 +65714,13 @@ var BABYLON;
             this.forceFullscreenViewport = true;
             /**
             * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+        *
+        * | Value | Type                                | Description |
+            * | ----- | ----------------------------------- | ----------- |
+            * | 1     | SCALEMODE_FLOOR                     | [engine.scalemode_floor](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |
+            * | 2     | SCALEMODE_NEAREST                   | [engine.scalemode_nearest](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |
+            * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |
+        *
             */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
             /**
@@ -86887,6 +86900,7 @@ var BABYLON;
             this._sceneDisposeObserver = this.originalScene.onDisposeObservable.add(function () {
                 _this.dispose();
             });
+            this._updateCamera();
         }
         /**
          * Renders the utility layers scene on top of the original scene
@@ -86930,10 +86944,11 @@ var BABYLON;
         function Gizmo(/** The utility layer the gizmo will be added to */ gizmoLayer) {
             var _this = this;
             this.gizmoLayer = gizmoLayer;
+            this._interactionsEnabled = true;
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode", gizmoLayer.utilityLayerScene);
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
                 if (_this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
-                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 5;
+                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 3;
                     _this._rootMesh.scaling.set(dist, dist, dist);
                 }
                 if (_this.attachedMesh) {
@@ -86941,6 +86956,22 @@ var BABYLON;
                 }
             });
         }
+        Gizmo.prototype._onInteractionsEnabledChanged = function (value) {
+        };
+        Object.defineProperty(Gizmo.prototype, "interactionsEnabled", {
+            get: function () {
+                return this._interactionsEnabled;
+            },
+            /**
+             * If interactions are enabled with this gizmo. (eg. dragging/rotation)
+             */
+            set: function (value) {
+                this._interactionsEnabled = value;
+                this._onInteractionsEnabledChanged(value);
+            },
+            enumerable: true,
+            configurable: true
+        });
         /**
          * Disposes of the gizmo
          */
@@ -86996,12 +87027,18 @@ var BABYLON;
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
                 if (_this.attachedMesh) {
                     _this.attachedMesh.position.addInPlace(event.delta);
                 }
             });
             return _this;
         }
+        AxisDragGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87020,6 +87057,162 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
+     * Single axis scale gizmo
+     */
+    var AxisScaleGizmo = /** @class */ (function (_super) {
+        __extends(AxisScaleGizmo, _super);
+        /**
+         * Creates an AxisScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param dragAxis The axis which the gizmo will be able to scale on
+         * @param color The color of the gizmo
+         */
+        function AxisScaleGizmo(gizmoLayer, dragAxis, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", { size: 1 }, gizmoLayer.utilityLayerScene);
+            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameter: 0.03, height: 0.2, tessellation: 96 }, gizmoLayer.utilityLayerScene);
+            _this._rootMesh.addChild(arrowMesh);
+            _this._rootMesh.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.1);
+            arrowMesh.material = coloredMaterial;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = coloredMaterial;
+            arrowTail.position.z += 0.2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh) {
+                    _this.attachedMesh.scaling.addInPlace(event.delta);
+                }
+            });
+            return _this;
+        }
+        AxisScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        AxisScaleGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return AxisScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.AxisScaleGizmo = AxisScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.axisScaleGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Single plane rotation gizmo
+     */
+    var PlaneRotationGizmo = /** @class */ (function (_super) {
+        __extends(PlaneRotationGizmo, _super);
+        /**
+         * Creates a PlaneRotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
+         * @param color The color of the gizmo
+         */
+        function PlaneRotationGizmo(gizmoLayer, planeNormal, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var rotationMesh = BABYLON.Mesh.CreateTorus("torus", 3, 0.3, 20, gizmoLayer.utilityLayerScene, false);
+            _this._rootMesh.addChild(rotationMesh);
+            // Position arrow pointing in its drag axis
+            rotationMesh.scaling.scaleInPlace(0.1);
+            rotationMesh.material = coloredMaterial;
+            rotationMesh.rotation.x = Math.PI / 2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(planeNormal));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragPlaneNormal: planeNormal, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            var lastDragPosition = null;
+            _this._dragBehavior.onDragStartObservable.add(function (e) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                lastDragPosition = e.dragPlanePoint;
+            });
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh && lastDragPosition) {
+                    if (!_this.attachedMesh.rotationQuaternion) {
+                        _this.attachedMesh.rotationQuaternion = new BABYLON.Quaternion();
+                    }
+                    // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)
+                    var newVector = event.dragPlanePoint.subtract(_this.attachedMesh.position).normalize();
+                    var originalVector = lastDragPosition.subtract(_this.attachedMesh.position).normalize();
+                    var cross = BABYLON.Vector3.Cross(newVector, originalVector);
+                    var dot = BABYLON.Vector3.Dot(newVector, originalVector);
+                    var angle = Math.atan2(cross.length(), dot);
+                    var up = planeNormal.clone();
+                    // Flip up vector depending on which side the camera is on
+                    if (gizmoLayer.utilityLayerScene.activeCamera) {
+                        var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(_this.attachedMesh.position);
+                        if (BABYLON.Vector3.Dot(camVec, up) > 0) {
+                            up.scaleInPlace(-1);
+                        }
+                    }
+                    var halfCircleSide = BABYLON.Vector3.Dot(up, cross) > 0.0;
+                    if (halfCircleSide)
+                        angle = -angle;
+                    // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
+                    var quaternionCoefficient = Math.sin(angle / 2);
+                    var amountToRotate = new BABYLON.Quaternion(up.x * quaternionCoefficient, up.y * quaternionCoefficient, up.z * quaternionCoefficient, Math.cos(angle / 2));
+                    // Rotate selected mesh quaternion over fixed axis
+                    amountToRotate.multiplyToRef(_this.attachedMesh.rotationQuaternion, _this.attachedMesh.rotationQuaternion);
+                    lastDragPosition = event.dragPlanePoint;
+                }
+            });
+            return _this;
+        }
+        PlaneRotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        PlaneRotationGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return PlaneRotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.PlaneRotationGizmo = PlaneRotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.planeRotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
      * Gizmo that enables dragging a mesh along 3 axis
      */
     var PositionGizmo = /** @class */ (function (_super) {
@@ -87044,6 +87237,11 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        PositionGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87059,6 +87257,102 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.positionGizmo.js.map
 
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables rotating a mesh along 3 axis
+     */
+    var RotationGizmo = /** @class */ (function (_super) {
+        __extends(RotationGizmo, _super);
+        /**
+         * Creates a RotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function RotationGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(RotationGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        RotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        RotationGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return RotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.RotationGizmo = RotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.rotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables scaling a mesh along 3 axis
+     */
+    var ScaleGizmo = /** @class */ (function (_super) {
+        __extends(ScaleGizmo, _super);
+        /**
+         * Creates a ScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function ScaleGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(ScaleGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        ScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        ScaleGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return ScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.ScaleGizmo = ScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.scaleGizmo.js.map
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -96604,6 +96898,10 @@ var BABYLON;
              *  Mesh with the position where the drag plane should be placed
              */
             this._dragPlaneParent = null;
+            /**
+             *  If the drag behavior will react to drag events
+             */
+            this.enabled = true;
             var optionCount = 0;
             if (options.dragAxis) {
                 optionCount++;
@@ -96657,6 +96955,9 @@ var BABYLON;
                 return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
             };
             this._pointerObserver = this.options.pointerObservableScene.onPrePointerObservable.add(function (pointerInfoPre, eventState) {
+                if (!_this.enabled) {
+                    return;
+                }
                 // Check if attached mesh is picked
                 var pickInfo = pointerInfoPre.ray ? _this._scene.pickWithRay(pointerInfoPre.ray, pickPredicate) : _this._scene.pick(_this._scene.pointerX, _this._scene.pointerY, pickPredicate);
                 if (pickInfo) {
@@ -96664,8 +96965,8 @@ var BABYLON;
                     if (!pickInfo.ray) {
                         pickInfo.ray = _this.options.pointerObservableScene.createPickingRay(_this._scene.pointerX, _this._scene.pointerY, BABYLON.Matrix.Identity(), _this._scene.activeCamera);
                     }
-                    if (pickInfo.hit) {
-                        eventState.skipNextObservers = true;
+                    if (pickInfo.hit && pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {
+                        pointerInfoPre.skipOnPointerObservable = true;
                     }
                 }
                 if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {

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


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


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

@@ -2245,7 +2245,7 @@ declare module BABYLON.GUI {
          * Gets or sets the texture scale ratio used to render content (2 by default)
          */
         contentScaleRatio: number;
-        protected _disposeFaceTexture(): void;
+        protected _disposeFacadeTexture(): void;
         private _resetContent();
         /**
          * Creates a new button

+ 15 - 9
dist/preview release/gui/babylon.gui.js

@@ -1455,7 +1455,7 @@ var BABYLON;
                 this._fontSet = false;
                 this._dummyVector2 = BABYLON.Vector2.Zero();
                 this._downCount = 0;
-                this._enterCount = 0;
+                this._enterCount = -1;
                 this._doNotRender = false;
                 this._downPointerIds = {};
                 /** Gets or sets a boolean indicating if the control can be hit with pointer events */
@@ -2527,9 +2527,12 @@ var BABYLON;
             };
             /** @hidden */
             Control.prototype._onPointerEnter = function (target) {
-                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 = this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
                 if (canNotify && this.parent != null)
@@ -2560,7 +2563,7 @@ var BABYLON;
                 this._downCount = 0;
                 delete this._downPointerIds[pointerId];
                 var canNotifyClick = notifyClick;
-                if (notifyClick && this._enterCount > 0) {
+                if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
                     canNotifyClick = this.onPointerClickObservable.notifyObservers(new GUI.Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
                 }
                 var canNotify = this.onPointerUpObservable.notifyObservers(new GUI.Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
@@ -6971,7 +6974,7 @@ var BABYLON;
             name) {
                 this.name = name;
                 this._downCount = 0;
-                this._enterCount = 0;
+                this._enterCount = -1;
                 this._downPointerIds = {};
                 this._isVisible = true;
                 /** Gets or sets the control position  in world space */
@@ -7178,9 +7181,12 @@ var BABYLON;
             };
             /** @hidden */
             Control3D.prototype._onPointerEnter = function (target) {
-                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);
                 if (this.pointerEnterAnimation) {
@@ -7213,7 +7219,7 @@ var BABYLON;
             Control3D.prototype._onPointerUp = function (target, coordinates, pointerId, buttonIndex, notifyClick) {
                 this._downCount = 0;
                 delete this._downPointerIds[pointerId];
-                if (notifyClick && this._enterCount > 0) {
+                if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
                     this.onPointerClickObservable.notifyObservers(new GUI.Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
                 }
                 this.onPointerUpObservable.notifyObservers(new GUI.Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
@@ -7459,14 +7465,14 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
-            Button3D.prototype._disposeFaceTexture = function () {
+            Button3D.prototype._disposeFacadeTexture = function () {
                 if (this._facadeTexture) {
                     this._facadeTexture.dispose();
                     this._facadeTexture = null;
                 }
             };
             Button3D.prototype._resetContent = function () {
-                this._disposeFaceTexture();
+                this._disposeFacadeTexture();
                 this.content = this._content;
             };
             Object.defineProperty(Button3D.prototype, "content", {
@@ -7654,7 +7660,7 @@ var BABYLON;
                 return "HolographicButton";
             };
             HolographicButton.prototype._rebuildContent = function () {
-                this._disposeFaceTexture();
+                this._disposeFacadeTexture();
                 var panel = new GUI.StackPanel();
                 panel.isVertical = true;
                 if (this._imageUrl) {

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


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

@@ -2250,7 +2250,7 @@ declare module BABYLON.GUI {
          * Gets or sets the texture scale ratio used to render content (2 by default)
          */
         contentScaleRatio: number;
-        protected _disposeFaceTexture(): void;
+        protected _disposeFacadeTexture(): void;
         private _resetContent();
         /**
          * Creates a new button

+ 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);

+ 14 - 3
dist/preview release/inspector/babylon.inspector.js

@@ -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) {

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


+ 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


+ 36 - 30
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,9 +689,13 @@ 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 */
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
-        /** Gets or sets extension name */
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
         /**
@@ -706,7 +703,9 @@ declare module BABYLON.GLTF2 {
          * @param loader defines the GLTFLoader to use
          */
         constructor(loader: GLTFLoader);
-        /** Release all resources */
+        /**
+         * Release all resources
+         */
         dispose(): void;
         /**
          * Override this method to modify the default behavior for loading scenes.
@@ -718,12 +717,16 @@ declare module BABYLON.GLTF2 {
          * @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.
+        /**
+         * Override this method to modify the default behavior for loading materials.
          * @hidden
          */
-        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>>;
         /**
          * Override this method to modify the default behavior for loading textures.
          * @hidden
@@ -738,7 +741,12 @@ declare module BABYLON.GLTF2 {
          * 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) => Promise<TResult>): Nullable<Promise<TResult>>;
+        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
@@ -758,7 +766,7 @@ declare module BABYLON.GLTF2 {
          * Helper method called by the loader to allow extensions to override loading materials.
          * @hidden
          */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        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
@@ -809,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.
@@ -823,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>>;
     }
 }
 
@@ -833,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>>;
     }
 }
 
@@ -860,7 +866,7 @@ declare module BABYLON.GLTF2.Extensions {
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
         /** @hidden */
-        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 _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -872,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);
     }
 }

+ 114 - 98
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 = {}));
 
@@ -2194,11 +2181,15 @@ var BABYLON;
              * @param loader defines the GLTFLoader to use
              */
             function GLTFLoaderExtension(loader) {
-                /** Gets or sets a boolean indicating if the extension is enabled */
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
-            /** Release all resources */
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
@@ -2213,12 +2204,16 @@ var BABYLON;
              * @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.
+            /**
+             * Override this method to modify the default behavior for loading materials.
              * @hidden
              */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
             /**
              * Override this method to modify the default behavior for loading textures.
              * @hidden
@@ -2243,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);
@@ -2257,6 +2252,29 @@ var BABYLON;
              * 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); });
             };
@@ -2278,8 +2296,8 @@ var BABYLON;
              * Helper method called by the loader to allow extensions to override loading materials.
              * @hidden
              */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            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.
@@ -2425,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) {
@@ -2442,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);
@@ -2541,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;
@@ -2595,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;
@@ -2757,7 +2773,7 @@ var BABYLON;
                     return _this;
                 }
                 /** @hidden */
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                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 || {};
@@ -2845,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


+ 36 - 30
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,9 +1266,13 @@ 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 */
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
-        /** Gets or sets extension name */
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
         /**
@@ -1283,7 +1280,9 @@ declare module BABYLON.GLTF2 {
          * @param loader defines the GLTFLoader to use
          */
         constructor(loader: GLTFLoader);
-        /** Release all resources */
+        /**
+         * Release all resources
+         */
         dispose(): void;
         /**
          * Override this method to modify the default behavior for loading scenes.
@@ -1295,12 +1294,16 @@ declare module BABYLON.GLTF2 {
          * @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.
+        /**
+         * Override this method to modify the default behavior for loading materials.
          * @hidden
          */
-        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>>;
         /**
          * Override this method to modify the default behavior for loading textures.
          * @hidden
@@ -1315,7 +1318,12 @@ declare module BABYLON.GLTF2 {
          * 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) => Promise<TResult>): Nullable<Promise<TResult>>;
+        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
@@ -1335,7 +1343,7 @@ declare module BABYLON.GLTF2 {
          * Helper method called by the loader to allow extensions to override loading materials.
          * @hidden
          */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        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
@@ -1386,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.
@@ -1400,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>>;
     }
 }
 
@@ -1410,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>>;
     }
 }
 
@@ -1437,7 +1443,7 @@ declare module BABYLON.GLTF2.Extensions {
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
         /** @hidden */
-        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 _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1449,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);
     }
 }

+ 117 - 99
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 = {}));
 
@@ -4410,11 +4397,15 @@ var BABYLON;
              * @param loader defines the GLTFLoader to use
              */
             function GLTFLoaderExtension(loader) {
-                /** Gets or sets a boolean indicating if the extension is enabled */
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
-            /** Release all resources */
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
@@ -4429,12 +4420,16 @@ var BABYLON;
              * @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.
+            /**
+             * Override this method to modify the default behavior for loading materials.
              * @hidden
              */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
             /**
              * Override this method to modify the default behavior for loading textures.
              * @hidden
@@ -4459,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);
@@ -4473,6 +4468,29 @@ var BABYLON;
              * 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); });
             };
@@ -4494,8 +4512,8 @@ var BABYLON;
              * Helper method called by the loader to allow extensions to override loading materials.
              * @hidden
              */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            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.
@@ -4641,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) {
@@ -4658,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);
@@ -4757,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;
@@ -4811,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;
@@ -4973,7 +4989,7 @@ var BABYLON;
                     return _this;
                 }
                 /** @hidden */
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                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 || {};
@@ -5061,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 || {};
@@ -5119,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


+ 36 - 30
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,9 +1362,13 @@ 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 */
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
-        /** Gets or sets extension name */
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
         /**
@@ -1379,7 +1376,9 @@ declare module BABYLON.GLTF2 {
          * @param loader defines the GLTFLoader to use
          */
         constructor(loader: GLTFLoader);
-        /** Release all resources */
+        /**
+         * Release all resources
+         */
         dispose(): void;
         /**
          * Override this method to modify the default behavior for loading scenes.
@@ -1391,12 +1390,16 @@ declare module BABYLON.GLTF2 {
          * @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.
+        /**
+         * Override this method to modify the default behavior for loading materials.
          * @hidden
          */
-        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>>;
         /**
          * Override this method to modify the default behavior for loading textures.
          * @hidden
@@ -1411,7 +1414,12 @@ declare module BABYLON.GLTF2 {
          * 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) => Promise<TResult>): Nullable<Promise<TResult>>;
+        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
@@ -1431,7 +1439,7 @@ declare module BABYLON.GLTF2 {
          * Helper method called by the loader to allow extensions to override loading materials.
          * @hidden
          */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        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
@@ -1482,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.
@@ -1496,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>>;
     }
 }
 
@@ -1506,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>>;
     }
 }
 
@@ -1533,7 +1539,7 @@ declare module BABYLON.GLTF2.Extensions {
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
         /** @hidden */
-        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 _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1545,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);
     }
 }

+ 117 - 99
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 = {}));
 
@@ -5392,11 +5379,15 @@ var BABYLON;
              * @param loader defines the GLTFLoader to use
              */
             function GLTFLoaderExtension(loader) {
-                /** Gets or sets a boolean indicating if the extension is enabled */
+                /**
+                 * Gets or sets a boolean indicating if the extension is enabled
+                 */
                 this.enabled = true;
                 this._loader = loader;
             }
-            /** Release all resources */
+            /**
+             * Release all resources
+             */
             GLTFLoaderExtension.prototype.dispose = function () {
                 delete this._loader;
             };
@@ -5411,12 +5402,16 @@ var BABYLON;
              * @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.
+            /**
+             * Override this method to modify the default behavior for loading materials.
              * @hidden
              */
-            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { return null; };
+            GLTFLoaderExtension.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) { return null; };
             /**
              * Override this method to modify the default behavior for loading textures.
              * @hidden
@@ -5441,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);
@@ -5455,6 +5450,29 @@ var BABYLON;
              * 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); });
             };
@@ -5476,8 +5494,8 @@ var BABYLON;
              * Helper method called by the loader to allow extensions to override loading materials.
              * @hidden
              */
-            GLTFLoaderExtension._LoadMaterialAsync = function (loader, context, material, babylonMesh, babylonDrawMode, assign) {
-                return loader._applyExtensions(function (extension) { return extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); });
+            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.
@@ -5614,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) {
@@ -5631,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);
@@ -5721,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;
@@ -5766,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;
@@ -5910,7 +5926,7 @@ var BABYLON;
                     return _this;
                 }
                 /** @hidden */
-                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                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 || {};
@@ -5989,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 || {};
@@ -6047,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


+ 36 - 30
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,9 +1369,13 @@ 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 */
+        /**
+         * Gets or sets a boolean indicating if the extension is enabled
+         */
         enabled: boolean;
-        /** Gets or sets extension name */
+        /**
+         * Gets or sets extension name
+         */
         readonly abstract name: string;
         protected _loader: GLTFLoader;
         /**
@@ -1386,7 +1383,9 @@ declare module BABYLON.GLTF2 {
          * @param loader defines the GLTFLoader to use
          */
         constructor(loader: GLTFLoader);
-        /** Release all resources */
+        /**
+         * Release all resources
+         */
         dispose(): void;
         /**
          * Override this method to modify the default behavior for loading scenes.
@@ -1398,12 +1397,16 @@ declare module BABYLON.GLTF2 {
          * @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.
+        /**
+         * Override this method to modify the default behavior for loading materials.
          * @hidden
          */
-        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>>;
         /**
          * Override this method to modify the default behavior for loading textures.
          * @hidden
@@ -1418,7 +1421,12 @@ declare module BABYLON.GLTF2 {
          * 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) => Promise<TResult>): Nullable<Promise<TResult>>;
+        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
@@ -1438,7 +1446,7 @@ declare module BABYLON.GLTF2 {
          * Helper method called by the loader to allow extensions to override loading materials.
          * @hidden
          */
-        static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        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
@@ -1489,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.
@@ -1503,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>>;
     }
 }
 
@@ -1513,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>>;
     }
 }
 
@@ -1540,7 +1546,7 @@ declare module BABYLON.GLTF2.Extensions {
     class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
         readonly name: string;
         /** @hidden */
-        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 _loadSpecularGlossinessPropertiesAsync(context, material, properties, babylonMaterial);
     }
 }
@@ -1552,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);
     }
 }

+ 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


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


+ 304 - 3
dist/preview release/viewer/babylon.viewer.max.js

@@ -19340,6 +19340,9 @@ var BABYLON;
                     this._updateNonUniformScalingState(false);
                 }
             }
+            else {
+                this._updateNonUniformScalingState(false);
+            }
             this._afterComputeWorldMatrix();
             // Absolute position
             this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
@@ -36693,6 +36696,9 @@ var BABYLON;
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices, null, updatable);
             }
+            else {
+                meshOrGeometry.setIndices([], null);
+            }
             return this;
         };
         VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
@@ -65829,6 +65835,13 @@ var BABYLON;
             this.forceFullscreenViewport = true;
             /**
             * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+        *
+        * | Value | Type                                | Description |
+            * | ----- | ----------------------------------- | ----------- |
+            * | 1     | SCALEMODE_FLOOR                     | [engine.scalemode_floor](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |
+            * | 2     | SCALEMODE_NEAREST                   | [engine.scalemode_nearest](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |
+            * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |
+        *
             */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
             /**
@@ -87008,6 +87021,7 @@ var BABYLON;
             this._sceneDisposeObserver = this.originalScene.onDisposeObservable.add(function () {
                 _this.dispose();
             });
+            this._updateCamera();
         }
         /**
          * Renders the utility layers scene on top of the original scene
@@ -87051,10 +87065,11 @@ var BABYLON;
         function Gizmo(/** The utility layer the gizmo will be added to */ gizmoLayer) {
             var _this = this;
             this.gizmoLayer = gizmoLayer;
+            this._interactionsEnabled = true;
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode", gizmoLayer.utilityLayerScene);
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
                 if (_this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
-                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 5;
+                    var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 3;
                     _this._rootMesh.scaling.set(dist, dist, dist);
                 }
                 if (_this.attachedMesh) {
@@ -87062,6 +87077,22 @@ var BABYLON;
                 }
             });
         }
+        Gizmo.prototype._onInteractionsEnabledChanged = function (value) {
+        };
+        Object.defineProperty(Gizmo.prototype, "interactionsEnabled", {
+            get: function () {
+                return this._interactionsEnabled;
+            },
+            /**
+             * If interactions are enabled with this gizmo. (eg. dragging/rotation)
+             */
+            set: function (value) {
+                this._interactionsEnabled = value;
+                this._onInteractionsEnabledChanged(value);
+            },
+            enumerable: true,
+            configurable: true
+        });
         /**
          * Disposes of the gizmo
          */
@@ -87117,12 +87148,18 @@ var BABYLON;
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
                 if (_this.attachedMesh) {
                     _this.attachedMesh.position.addInPlace(event.delta);
                 }
             });
             return _this;
         }
+        AxisDragGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87141,6 +87178,162 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
+     * Single axis scale gizmo
+     */
+    var AxisScaleGizmo = /** @class */ (function (_super) {
+        __extends(AxisScaleGizmo, _super);
+        /**
+         * Creates an AxisScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param dragAxis The axis which the gizmo will be able to scale on
+         * @param color The color of the gizmo
+         */
+        function AxisScaleGizmo(gizmoLayer, dragAxis, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", { size: 1 }, gizmoLayer.utilityLayerScene);
+            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameter: 0.03, height: 0.2, tessellation: 96 }, gizmoLayer.utilityLayerScene);
+            _this._rootMesh.addChild(arrowMesh);
+            _this._rootMesh.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.1);
+            arrowMesh.material = coloredMaterial;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = coloredMaterial;
+            arrowTail.position.z += 0.2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh) {
+                    _this.attachedMesh.scaling.addInPlace(event.delta);
+                }
+            });
+            return _this;
+        }
+        AxisScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        AxisScaleGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return AxisScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.AxisScaleGizmo = AxisScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.axisScaleGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Single plane rotation gizmo
+     */
+    var PlaneRotationGizmo = /** @class */ (function (_super) {
+        __extends(PlaneRotationGizmo, _super);
+        /**
+         * Creates a PlaneRotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
+         * @param color The color of the gizmo
+         */
+        function PlaneRotationGizmo(gizmoLayer, planeNormal, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build mesh on root node
+            var rotationMesh = BABYLON.Mesh.CreateTorus("torus", 3, 0.3, 20, gizmoLayer.utilityLayerScene, false);
+            _this._rootMesh.addChild(rotationMesh);
+            // Position arrow pointing in its drag axis
+            rotationMesh.scaling.scaleInPlace(0.1);
+            rotationMesh.material = coloredMaterial;
+            rotationMesh.rotation.x = Math.PI / 2;
+            _this._rootMesh.lookAt(_this._rootMesh.position.subtract(planeNormal));
+            // Add drag behavior to handle events when the gizmo is dragged
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragPlaneNormal: planeNormal, pointerObservableScene: gizmoLayer.originalScene });
+            _this._dragBehavior.moveAttached = false;
+            _this._rootMesh.addBehavior(_this._dragBehavior);
+            var lastDragPosition = null;
+            _this._dragBehavior.onDragStartObservable.add(function (e) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                lastDragPosition = e.dragPlanePoint;
+            });
+            _this._dragBehavior.onDragObservable.add(function (event) {
+                if (!_this.interactionsEnabled) {
+                    return;
+                }
+                if (_this.attachedMesh && lastDragPosition) {
+                    if (!_this.attachedMesh.rotationQuaternion) {
+                        _this.attachedMesh.rotationQuaternion = new BABYLON.Quaternion();
+                    }
+                    // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)
+                    var newVector = event.dragPlanePoint.subtract(_this.attachedMesh.position).normalize();
+                    var originalVector = lastDragPosition.subtract(_this.attachedMesh.position).normalize();
+                    var cross = BABYLON.Vector3.Cross(newVector, originalVector);
+                    var dot = BABYLON.Vector3.Dot(newVector, originalVector);
+                    var angle = Math.atan2(cross.length(), dot);
+                    var up = planeNormal.clone();
+                    // Flip up vector depending on which side the camera is on
+                    if (gizmoLayer.utilityLayerScene.activeCamera) {
+                        var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(_this.attachedMesh.position);
+                        if (BABYLON.Vector3.Dot(camVec, up) > 0) {
+                            up.scaleInPlace(-1);
+                        }
+                    }
+                    var halfCircleSide = BABYLON.Vector3.Dot(up, cross) > 0.0;
+                    if (halfCircleSide)
+                        angle = -angle;
+                    // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
+                    var quaternionCoefficient = Math.sin(angle / 2);
+                    var amountToRotate = new BABYLON.Quaternion(up.x * quaternionCoefficient, up.y * quaternionCoefficient, up.z * quaternionCoefficient, Math.cos(angle / 2));
+                    // Rotate selected mesh quaternion over fixed axis
+                    amountToRotate.multiplyToRef(_this.attachedMesh.rotationQuaternion, _this.attachedMesh.rotationQuaternion);
+                    lastDragPosition = event.dragPlanePoint;
+                }
+            });
+            return _this;
+        }
+        PlaneRotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._dragBehavior.enabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        PlaneRotationGizmo.prototype.dispose = function () {
+            this._dragBehavior.detach();
+            _super.prototype.dispose.call(this);
+        };
+        return PlaneRotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.PlaneRotationGizmo = PlaneRotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.planeRotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
      * Gizmo that enables dragging a mesh along 3 axis
      */
     var PositionGizmo = /** @class */ (function (_super) {
@@ -87165,6 +87358,11 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        PositionGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
         /**
          * Disposes of the gizmo
          */
@@ -87180,6 +87378,102 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.positionGizmo.js.map
 
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables rotating a mesh along 3 axis
+     */
+    var RotationGizmo = /** @class */ (function (_super) {
+        __extends(RotationGizmo, _super);
+        /**
+         * Creates a RotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function RotationGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.PlaneRotationGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(RotationGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        RotationGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        RotationGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return RotationGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.RotationGizmo = RotationGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.rotationGizmo.js.map
+
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Gizmo that enables scaling a mesh along 3 axis
+     */
+    var ScaleGizmo = /** @class */ (function (_super) {
+        __extends(ScaleGizmo, _super);
+        /**
+         * Creates a ScaleGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         */
+        function ScaleGizmo(gizmoLayer) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._xDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.FromHexString("#00b894"));
+            _this._yDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.FromHexString("#d63031"));
+            _this._zDrag = new BABYLON.AxisScaleGizmo(gizmoLayer, new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.FromHexString("#0984e3"));
+            return _this;
+        }
+        Object.defineProperty(ScaleGizmo.prototype, "attachedMesh", {
+            set: function (mesh) {
+                this._xDrag.attachedMesh = mesh;
+                this._yDrag.attachedMesh = mesh;
+                this._zDrag.attachedMesh = mesh;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        ScaleGizmo.prototype._onInteractionsEnabledChanged = function (value) {
+            this._xDrag.interactionsEnabled = value;
+            this._yDrag.interactionsEnabled = value;
+            this._zDrag.interactionsEnabled = value;
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        ScaleGizmo.prototype.dispose = function () {
+            this._xDrag.dispose();
+            this._yDrag.dispose();
+            this._zDrag.dispose();
+        };
+        return ScaleGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.ScaleGizmo = ScaleGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.scaleGizmo.js.map
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -96725,6 +97019,10 @@ var BABYLON;
              *  Mesh with the position where the drag plane should be placed
              */
             this._dragPlaneParent = null;
+            /**
+             *  If the drag behavior will react to drag events
+             */
+            this.enabled = true;
             var optionCount = 0;
             if (options.dragAxis) {
                 optionCount++;
@@ -96778,6 +97076,9 @@ var BABYLON;
                 return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
             };
             this._pointerObserver = this.options.pointerObservableScene.onPrePointerObservable.add(function (pointerInfoPre, eventState) {
+                if (!_this.enabled) {
+                    return;
+                }
                 // Check if attached mesh is picked
                 var pickInfo = pointerInfoPre.ray ? _this._scene.pickWithRay(pointerInfoPre.ray, pickPredicate) : _this._scene.pick(_this._scene.pointerX, _this._scene.pointerY, pickPredicate);
                 if (pickInfo) {
@@ -96785,8 +97086,8 @@ var BABYLON;
                     if (!pickInfo.ray) {
                         pickInfo.ray = _this.options.pointerObservableScene.createPickingRay(_this._scene.pointerX, _this._scene.pointerY, BABYLON.Matrix.Identity(), _this._scene.activeCamera);
                     }
-                    if (pickInfo.hit) {
-                        eventState.skipNextObservers = true;
+                    if (pickInfo.hit && pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {
+                        pointerInfoPre.skipOnPointerObservable = true;
                     }
                 }
                 if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {