David Catuhe 6 年之前
父节点
当前提交
383844058e
共有 30 个文件被更改,包括 28014 次插入27371 次删除
  1. 14731 14650
      Playground/babylon.d.txt
  2. 二进制
      Playground/textures/gui/backgroundImage-vertical.png
  3. 二进制
      Playground/textures/gui/valueImage-vertical.png
  4. 12710 12631
      dist/preview release/babylon.d.ts
  5. 1 1
      dist/preview release/babylon.js
  6. 162 4
      dist/preview release/babylon.max.js
  7. 162 4
      dist/preview release/babylon.no-module.max.js
  8. 1 1
      dist/preview release/babylon.worker.js
  9. 164 6
      dist/preview release/es6.js
  10. 4 2
      dist/preview release/gui/babylon.gui.d.ts
  11. 1 1
      dist/preview release/gui/babylon.gui.js
  12. 1 1
      dist/preview release/gui/babylon.gui.min.js
  13. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  14. 8 4
      dist/preview release/gui/babylon.gui.module.d.ts
  15. 3 0
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  16. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  17. 3 0
      dist/preview release/loaders/babylon.glTFFileLoader.js
  18. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  19. 3 0
      dist/preview release/loaders/babylonjs.loaders.js
  20. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  21. 1 15
      dist/preview release/viewer/babylon.viewer.d.ts
  22. 1 1
      dist/preview release/viewer/babylon.viewer.js
  23. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  24. 1 18
      dist/preview release/viewer/babylon.viewer.module.d.ts
  25. 2 0
      dist/preview release/what's new.md
  26. 20 3
      gui/src/2D/controls/baseSlider.ts
  27. 23 7
      gui/src/2D/controls/imageBasedSlider.ts
  28. 1 16
      gui/src/2D/controls/slider.ts
  29. 二进制
      tests/validation/ReferenceImages/Sliders.png
  30. 5 0
      tests/validation/config.json

文件差异内容过多而无法显示
+ 14731 - 14650
Playground/babylon.d.txt


二进制
Playground/textures/gui/backgroundImage-vertical.png


二进制
Playground/textures/gui/valueImage-vertical.png


文件差异内容过多而无法显示
+ 12710 - 12631
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.js


+ 162 - 4
dist/preview release/babylon.max.js

@@ -108859,6 +108859,14 @@ var BABYLON;
             });
         };
         /**
+         * Fires a ray and returns the closest hit in the xr sessions enviornment, useful to place objects in AR
+         * @param ray ray to cast into the environment
+         * @returns Promise which resolves with a collision point in the environment if it exists
+         */
+        WebXRExperienceHelper.prototype.environmentPointHitTest = function (ray) {
+            return this._sessionManager.environmentPointHitTest(ray);
+        };
+        /**
          * Checks if the creation options are supported by the xr session
          * @param options creation options
          * @returns true if supported
@@ -108923,6 +108931,32 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
 var BABYLON;
 (function (BABYLON) {
     /**
+     * Button which can be used to enter a different mode of XR
+     */
+    var WebXREnterExitUIButton = /** @class */ (function () {
+        /**
+         * Creates a WebXREnterExitUIButton
+         * @param element button element
+         * @param initializationOptions XR initialization options for the button
+         */
+        function WebXREnterExitUIButton(
+        /** button element */
+        element, 
+        /** XR initialization options for the button */
+        initializationOptions) {
+            this.element = element;
+            this.initializationOptions = initializationOptions;
+        }
+        /**
+         * Overwritable function which can be used to update the button's visuals when the state changes
+         * @param activeButton the current active button in the UI
+         */
+        WebXREnterExitUIButton.prototype.update = function (activeButton) {
+        };
+        return WebXREnterExitUIButton;
+    }());
+    BABYLON.WebXREnterExitUIButton = WebXREnterExitUIButton;
+    /**
      * Options to create the webXR UI
      */
     var WebXREnterExitUIOptions = /** @class */ (function () {
@@ -108939,6 +108973,7 @@ var BABYLON;
             var _this = this;
             this.scene = scene;
             this._buttons = [];
+            this._activeButton = null;
             this._overlay = document.createElement("div");
             this._overlay.style.cssText = "z-index:11;position: absolute; right: 20px;bottom: 50px;";
             if (options.customButtons) {
@@ -108948,11 +108983,20 @@ var BABYLON;
                 var hmdBtn = document.createElement("button");
                 hmdBtn.style.cssText = "color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-repeat:no-repeat; background-position: center; outline: none;";
                 hmdBtn.innerText = "HMD";
-                this._buttons.push({ element: hmdBtn, initializationOptions: { immersive: true } });
+                this._buttons.push(new WebXREnterExitUIButton(hmdBtn, { immersive: true, outputContext: options.outputCanvasContext }));
+                this._buttons[this._buttons.length - 1].update = function (activeButton) {
+                    this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
+                    this.element.innerText = activeButton === this ? "EXIT" : "HMD";
+                };
                 var windowBtn = document.createElement("button");
                 windowBtn.style.cssText = hmdBtn.style.cssText;
                 windowBtn.innerText = "Window";
-                this._buttons.push({ element: windowBtn, initializationOptions: { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext } });
+                this._buttons.push(new WebXREnterExitUIButton(windowBtn, { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext }));
+                this._buttons[this._buttons.length - 1].update = function (activeButton) {
+                    this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
+                    this.element.innerText = activeButton === this ? "EXIT" : "Window";
+                };
+                this._updateButtons(null);
             }
             var renderCanvas = scene.getEngine().getRenderingCanvas();
             if (renderCanvas && renderCanvas.parentNode) {
@@ -108975,6 +109019,11 @@ var BABYLON;
             var supportedPromises = ui._buttons.map(function (btn) {
                 return helper.supportsSession(btn.initializationOptions);
             });
+            helper.onStateChangedObservable.add(function (state) {
+                if (state == BABYLON.WebXRState.NOT_IN_XR) {
+                    ui._updateButtons(null);
+                }
+            });
             return Promise.all(supportedPromises).then(function (results) {
                 results.forEach(function (supported, i) {
                     if (supported) {
@@ -108984,12 +109033,14 @@ var BABYLON;
                                 switch (_a.label) {
                                     case 0:
                                         if (!(helper.state == BABYLON.WebXRState.IN_XR)) return [3 /*break*/, 2];
+                                        ui._updateButtons(null);
                                         return [4 /*yield*/, helper.exitXR()];
                                     case 1:
                                         _a.sent();
                                         return [2 /*return*/];
                                     case 2:
                                         if (!(helper.state == BABYLON.WebXRState.NOT_IN_XR)) return [3 /*break*/, 4];
+                                        ui._updateButtons(ui._buttons[i]);
                                         return [4 /*yield*/, helper.enterXR(ui._buttons[i].initializationOptions, "eye-level")];
                                     case 3:
                                         _a.sent();
@@ -109002,6 +109053,13 @@ var BABYLON;
                 });
             });
         };
+        WebXREnterExitUI.prototype._updateButtons = function (activeButton) {
+            var _this = this;
+            this._activeButton = activeButton;
+            this._buttons.forEach(function (b) {
+                b.update(_this._activeButton);
+            });
+        };
         /**
          * Disposes of the object
          */
@@ -109038,7 +109096,7 @@ var BABYLON;
             this.canvasContext = null;
             if (!canvas) {
                 canvas = document.createElement('canvas');
-                canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #48989e;";
+                canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #000000;";
             }
             this._setManagedOutputCanvas(canvas);
             helper.onStateChangedObservable.add(function (stateInfo) {
@@ -109086,6 +109144,104 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.webXRManagedOutputCanvas.js.map
 
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Represents an XR input
+     */
+    var WebXRController = /** @class */ (function () {
+        /**
+         * Creates the controller
+         * @see https://doc.babylonjs.com/how_to/webxr
+         * @param scene the scene which the controller should be associated to
+         */
+        function WebXRController(scene) {
+            this.pointer = new BABYLON.AbstractMesh("controllerPointer", scene);
+        }
+        /**
+         * Disposes of the object
+         */
+        WebXRController.prototype.dispose = function () {
+            if (this.grip) {
+                this.grip.dispose();
+            }
+            this.pointer.dispose();
+        };
+        return WebXRController;
+    }());
+    BABYLON.WebXRController = WebXRController;
+    /**
+     * XR input used to track XR inputs such as controllers/rays
+     */
+    var WebXRInput = /** @class */ (function () {
+        /**
+         * Initializes the WebXRInput
+         * @param helper experience helper which the input should be created for
+         */
+        function WebXRInput(helper) {
+            var _this = this;
+            this.helper = helper;
+            /**
+             * XR controllers being tracked
+             */
+            this.controllers = [];
+            this._tmpMatrix = new BABYLON.Matrix();
+            this._frameObserver = helper._sessionManager.onXRFrameObservable.add(function () {
+                if (!helper._sessionManager._currentXRFrame || !helper._sessionManager._currentXRFrame.getDevicePose) {
+                    return false;
+                }
+                var xrFrame = helper._sessionManager._currentXRFrame;
+                var inputSources = helper._sessionManager._xrSession.getInputSources();
+                inputSources.forEach(function (input, i) {
+                    var inputPose = xrFrame.getInputPose(input, helper._sessionManager._frameOfReference);
+                    if (inputPose) {
+                        if (_this.controllers.length <= i) {
+                            _this.controllers.push(new WebXRController(helper.container.getScene()));
+                        }
+                        var controller = _this.controllers[i];
+                        // Manage the grip if it exists
+                        if (inputPose.gripMatrix) {
+                            if (!controller.grip) {
+                                controller.grip = new BABYLON.AbstractMesh("controllerGrip", helper.container.getScene());
+                            }
+                            BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.gripMatrix, 0, 1, _this._tmpMatrix);
+                            if (!controller.grip.getScene().useRightHandedSystem) {
+                                _this._tmpMatrix.toggleModelMatrixHandInPlace();
+                            }
+                            if (!controller.grip.rotationQuaternion) {
+                                controller.grip.rotationQuaternion = new BABYLON.Quaternion();
+                            }
+                            _this._tmpMatrix.decompose(controller.grip.scaling, controller.grip.rotationQuaternion, controller.grip.position);
+                        }
+                        // Manager pointer of controller
+                        BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.targetRay.transformMatrix, 0, 1, _this._tmpMatrix);
+                        if (!controller.pointer.getScene().useRightHandedSystem) {
+                            _this._tmpMatrix.toggleModelMatrixHandInPlace();
+                        }
+                        if (!controller.pointer.rotationQuaternion) {
+                            controller.pointer.rotationQuaternion = new BABYLON.Quaternion();
+                        }
+                        _this._tmpMatrix.decompose(controller.pointer.scaling, controller.pointer.rotationQuaternion, controller.pointer.position);
+                    }
+                });
+            });
+        }
+        /**
+         * Disposes of the object
+         */
+        WebXRInput.prototype.dispose = function () {
+            this.controllers.forEach(function (c) {
+                c.dispose();
+            });
+            this.helper._sessionManager.onXRFrameObservable.remove(this._frameObserver);
+        };
+        return WebXRInput;
+    }());
+    BABYLON.WebXRInput = WebXRInput;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.webXRInput.js.map
+
 // Mainly based on these 2 articles :
 // Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx
 // & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
@@ -119986,7 +120142,9 @@ var BABYLON;
         var _this = this;
         return BABYLON.WebXRExperienceHelper.CreateAsync(this).then(function (helper) {
             var outputCanvas = new BABYLON.WebXRManagedOutputCanvas(helper);
-            return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext }).then(function (ui) {
+            return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext })
+                .then(function (ui) {
+                new BABYLON.WebXRInput(helper);
                 return helper;
             });
         });

+ 162 - 4
dist/preview release/babylon.no-module.max.js

@@ -108826,6 +108826,14 @@ var BABYLON;
             });
         };
         /**
+         * Fires a ray and returns the closest hit in the xr sessions enviornment, useful to place objects in AR
+         * @param ray ray to cast into the environment
+         * @returns Promise which resolves with a collision point in the environment if it exists
+         */
+        WebXRExperienceHelper.prototype.environmentPointHitTest = function (ray) {
+            return this._sessionManager.environmentPointHitTest(ray);
+        };
+        /**
          * Checks if the creation options are supported by the xr session
          * @param options creation options
          * @returns true if supported
@@ -108890,6 +108898,32 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
 var BABYLON;
 (function (BABYLON) {
     /**
+     * Button which can be used to enter a different mode of XR
+     */
+    var WebXREnterExitUIButton = /** @class */ (function () {
+        /**
+         * Creates a WebXREnterExitUIButton
+         * @param element button element
+         * @param initializationOptions XR initialization options for the button
+         */
+        function WebXREnterExitUIButton(
+        /** button element */
+        element, 
+        /** XR initialization options for the button */
+        initializationOptions) {
+            this.element = element;
+            this.initializationOptions = initializationOptions;
+        }
+        /**
+         * Overwritable function which can be used to update the button's visuals when the state changes
+         * @param activeButton the current active button in the UI
+         */
+        WebXREnterExitUIButton.prototype.update = function (activeButton) {
+        };
+        return WebXREnterExitUIButton;
+    }());
+    BABYLON.WebXREnterExitUIButton = WebXREnterExitUIButton;
+    /**
      * Options to create the webXR UI
      */
     var WebXREnterExitUIOptions = /** @class */ (function () {
@@ -108906,6 +108940,7 @@ var BABYLON;
             var _this = this;
             this.scene = scene;
             this._buttons = [];
+            this._activeButton = null;
             this._overlay = document.createElement("div");
             this._overlay.style.cssText = "z-index:11;position: absolute; right: 20px;bottom: 50px;";
             if (options.customButtons) {
@@ -108915,11 +108950,20 @@ var BABYLON;
                 var hmdBtn = document.createElement("button");
                 hmdBtn.style.cssText = "color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-repeat:no-repeat; background-position: center; outline: none;";
                 hmdBtn.innerText = "HMD";
-                this._buttons.push({ element: hmdBtn, initializationOptions: { immersive: true } });
+                this._buttons.push(new WebXREnterExitUIButton(hmdBtn, { immersive: true, outputContext: options.outputCanvasContext }));
+                this._buttons[this._buttons.length - 1].update = function (activeButton) {
+                    this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
+                    this.element.innerText = activeButton === this ? "EXIT" : "HMD";
+                };
                 var windowBtn = document.createElement("button");
                 windowBtn.style.cssText = hmdBtn.style.cssText;
                 windowBtn.innerText = "Window";
-                this._buttons.push({ element: windowBtn, initializationOptions: { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext } });
+                this._buttons.push(new WebXREnterExitUIButton(windowBtn, { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext }));
+                this._buttons[this._buttons.length - 1].update = function (activeButton) {
+                    this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
+                    this.element.innerText = activeButton === this ? "EXIT" : "Window";
+                };
+                this._updateButtons(null);
             }
             var renderCanvas = scene.getEngine().getRenderingCanvas();
             if (renderCanvas && renderCanvas.parentNode) {
@@ -108942,6 +108986,11 @@ var BABYLON;
             var supportedPromises = ui._buttons.map(function (btn) {
                 return helper.supportsSession(btn.initializationOptions);
             });
+            helper.onStateChangedObservable.add(function (state) {
+                if (state == BABYLON.WebXRState.NOT_IN_XR) {
+                    ui._updateButtons(null);
+                }
+            });
             return Promise.all(supportedPromises).then(function (results) {
                 results.forEach(function (supported, i) {
                     if (supported) {
@@ -108951,12 +109000,14 @@ var BABYLON;
                                 switch (_a.label) {
                                     case 0:
                                         if (!(helper.state == BABYLON.WebXRState.IN_XR)) return [3 /*break*/, 2];
+                                        ui._updateButtons(null);
                                         return [4 /*yield*/, helper.exitXR()];
                                     case 1:
                                         _a.sent();
                                         return [2 /*return*/];
                                     case 2:
                                         if (!(helper.state == BABYLON.WebXRState.NOT_IN_XR)) return [3 /*break*/, 4];
+                                        ui._updateButtons(ui._buttons[i]);
                                         return [4 /*yield*/, helper.enterXR(ui._buttons[i].initializationOptions, "eye-level")];
                                     case 3:
                                         _a.sent();
@@ -108969,6 +109020,13 @@ var BABYLON;
                 });
             });
         };
+        WebXREnterExitUI.prototype._updateButtons = function (activeButton) {
+            var _this = this;
+            this._activeButton = activeButton;
+            this._buttons.forEach(function (b) {
+                b.update(_this._activeButton);
+            });
+        };
         /**
          * Disposes of the object
          */
@@ -109005,7 +109063,7 @@ var BABYLON;
             this.canvasContext = null;
             if (!canvas) {
                 canvas = document.createElement('canvas');
-                canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #48989e;";
+                canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #000000;";
             }
             this._setManagedOutputCanvas(canvas);
             helper.onStateChangedObservable.add(function (stateInfo) {
@@ -109053,6 +109111,104 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.webXRManagedOutputCanvas.js.map
 
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Represents an XR input
+     */
+    var WebXRController = /** @class */ (function () {
+        /**
+         * Creates the controller
+         * @see https://doc.babylonjs.com/how_to/webxr
+         * @param scene the scene which the controller should be associated to
+         */
+        function WebXRController(scene) {
+            this.pointer = new BABYLON.AbstractMesh("controllerPointer", scene);
+        }
+        /**
+         * Disposes of the object
+         */
+        WebXRController.prototype.dispose = function () {
+            if (this.grip) {
+                this.grip.dispose();
+            }
+            this.pointer.dispose();
+        };
+        return WebXRController;
+    }());
+    BABYLON.WebXRController = WebXRController;
+    /**
+     * XR input used to track XR inputs such as controllers/rays
+     */
+    var WebXRInput = /** @class */ (function () {
+        /**
+         * Initializes the WebXRInput
+         * @param helper experience helper which the input should be created for
+         */
+        function WebXRInput(helper) {
+            var _this = this;
+            this.helper = helper;
+            /**
+             * XR controllers being tracked
+             */
+            this.controllers = [];
+            this._tmpMatrix = new BABYLON.Matrix();
+            this._frameObserver = helper._sessionManager.onXRFrameObservable.add(function () {
+                if (!helper._sessionManager._currentXRFrame || !helper._sessionManager._currentXRFrame.getDevicePose) {
+                    return false;
+                }
+                var xrFrame = helper._sessionManager._currentXRFrame;
+                var inputSources = helper._sessionManager._xrSession.getInputSources();
+                inputSources.forEach(function (input, i) {
+                    var inputPose = xrFrame.getInputPose(input, helper._sessionManager._frameOfReference);
+                    if (inputPose) {
+                        if (_this.controllers.length <= i) {
+                            _this.controllers.push(new WebXRController(helper.container.getScene()));
+                        }
+                        var controller = _this.controllers[i];
+                        // Manage the grip if it exists
+                        if (inputPose.gripMatrix) {
+                            if (!controller.grip) {
+                                controller.grip = new BABYLON.AbstractMesh("controllerGrip", helper.container.getScene());
+                            }
+                            BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.gripMatrix, 0, 1, _this._tmpMatrix);
+                            if (!controller.grip.getScene().useRightHandedSystem) {
+                                _this._tmpMatrix.toggleModelMatrixHandInPlace();
+                            }
+                            if (!controller.grip.rotationQuaternion) {
+                                controller.grip.rotationQuaternion = new BABYLON.Quaternion();
+                            }
+                            _this._tmpMatrix.decompose(controller.grip.scaling, controller.grip.rotationQuaternion, controller.grip.position);
+                        }
+                        // Manager pointer of controller
+                        BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.targetRay.transformMatrix, 0, 1, _this._tmpMatrix);
+                        if (!controller.pointer.getScene().useRightHandedSystem) {
+                            _this._tmpMatrix.toggleModelMatrixHandInPlace();
+                        }
+                        if (!controller.pointer.rotationQuaternion) {
+                            controller.pointer.rotationQuaternion = new BABYLON.Quaternion();
+                        }
+                        _this._tmpMatrix.decompose(controller.pointer.scaling, controller.pointer.rotationQuaternion, controller.pointer.position);
+                    }
+                });
+            });
+        }
+        /**
+         * Disposes of the object
+         */
+        WebXRInput.prototype.dispose = function () {
+            this.controllers.forEach(function (c) {
+                c.dispose();
+            });
+            this.helper._sessionManager.onXRFrameObservable.remove(this._frameObserver);
+        };
+        return WebXRInput;
+    }());
+    BABYLON.WebXRInput = WebXRInput;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.webXRInput.js.map
+
 // Mainly based on these 2 articles :
 // Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx
 // & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
@@ -119953,7 +120109,9 @@ var BABYLON;
         var _this = this;
         return BABYLON.WebXRExperienceHelper.CreateAsync(this).then(function (helper) {
             var outputCanvas = new BABYLON.WebXRManagedOutputCanvas(helper);
-            return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext }).then(function (ui) {
+            return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext })
+                .then(function (ui) {
+                new BABYLON.WebXRInput(helper);
                 return helper;
             });
         });

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 164 - 6
dist/preview release/es6.js


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

@@ -2082,6 +2082,7 @@ declare module BABYLON.GUI {
             name?: string | undefined;
             protected _thumbWidth: ValueAndUnit;
             protected _barOffset: ValueAndUnit;
+            protected _displayThumb: boolean;
             protected _effectiveBarOffset: number;
             protected _renderLeft: number;
             protected _renderTop: number;
@@ -2092,6 +2093,8 @@ declare module BABYLON.GUI {
             protected _effectiveThumbThickness: number;
             /** BABYLON.Observable raised when the sldier value changes */
             onValueChangedObservable: BABYLON.Observable<number>;
+            /** Gets or sets a boolean indicating if the thumb must be rendered */
+            displayThumb: boolean;
             /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
             barOffset: string | number;
             /** Gets main bar offset in pixels*/
@@ -2130,8 +2133,6 @@ declare module BABYLON.GUI {
         */
     export class Slider extends BaseSlider {
             name?: string | undefined;
-            /** Gets or sets a boolean indicating if the thumb must be rendered */
-            displayThumb: boolean;
             /** Gets or sets border color */
             borderColor: string;
             /** Gets or sets background color */
@@ -2153,6 +2154,7 @@ declare module BABYLON.GUI {
         */
     export class ImageBasedSlider extends BaseSlider {
             name?: string | undefined;
+            displayThumb: boolean;
             /**
                 * Gets or sets the image used to render the background
                 */

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


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

@@ -2246,6 +2246,7 @@ declare module 'babylonjs-gui/2D/controls/baseSlider' {
             name?: string | undefined;
             protected _thumbWidth: ValueAndUnit;
             protected _barOffset: ValueAndUnit;
+            protected _displayThumb: boolean;
             protected _effectiveBarOffset: number;
             protected _renderLeft: number;
             protected _renderTop: number;
@@ -2256,6 +2257,8 @@ declare module 'babylonjs-gui/2D/controls/baseSlider' {
             protected _effectiveThumbThickness: number;
             /** Observable raised when the sldier value changes */
             onValueChangedObservable: Observable<number>;
+            /** Gets or sets a boolean indicating if the thumb must be rendered */
+            displayThumb: boolean;
             /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
             barOffset: string | number;
             /** Gets main bar offset in pixels*/
@@ -2297,8 +2300,6 @@ declare module 'babylonjs-gui/2D/controls/slider' {
         */
     export class Slider extends BaseSlider {
             name?: string | undefined;
-            /** Gets or sets a boolean indicating if the thumb must be rendered */
-            displayThumb: boolean;
             /** Gets or sets border color */
             borderColor: string;
             /** Gets or sets background color */
@@ -2324,6 +2325,7 @@ declare module 'babylonjs-gui/2D/controls/imageBasedSlider' {
         */
     export class ImageBasedSlider extends BaseSlider {
             name?: string | undefined;
+            displayThumb: boolean;
             /**
                 * Gets or sets the image used to render the background
                 */
@@ -5008,6 +5010,7 @@ declare module BABYLON.GUI {
             name?: string | undefined;
             protected _thumbWidth: ValueAndUnit;
             protected _barOffset: ValueAndUnit;
+            protected _displayThumb: boolean;
             protected _effectiveBarOffset: number;
             protected _renderLeft: number;
             protected _renderTop: number;
@@ -5018,6 +5021,8 @@ declare module BABYLON.GUI {
             protected _effectiveThumbThickness: number;
             /** BABYLON.Observable raised when the sldier value changes */
             onValueChangedObservable: BABYLON.Observable<number>;
+            /** Gets or sets a boolean indicating if the thumb must be rendered */
+            displayThumb: boolean;
             /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
             barOffset: string | number;
             /** Gets main bar offset in pixels*/
@@ -5056,8 +5061,6 @@ declare module BABYLON.GUI {
         */
     export class Slider extends BaseSlider {
             name?: string | undefined;
-            /** Gets or sets a boolean indicating if the thumb must be rendered */
-            displayThumb: boolean;
             /** Gets or sets border color */
             borderColor: string;
             /** Gets or sets background color */
@@ -5079,6 +5082,7 @@ declare module BABYLON.GUI {
         */
     export class ImageBasedSlider extends BaseSlider {
             name?: string | undefined;
+            displayThumb: boolean;
             /**
                 * Gets or sets the image used to render the background
                 */

+ 3 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -1637,6 +1637,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
                 var _this = this;
+                if (channel.target.node == undefined) {
+                    return Promise.resolve();
+                }
                 var targetNode = ArrayItem.Get(context + "/target/node", this.gltf.nodes, channel.target.node);
                 // Ignore animations that have no animation targets.
                 if ((channel.target.path === "weights" /* WEIGHTS */ && !targetNode._numMorphTargets) ||

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 3 - 0
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3845,6 +3845,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
                 var _this = this;
+                if (channel.target.node == undefined) {
+                    return Promise.resolve();
+                }
                 var targetNode = ArrayItem.Get(context + "/target/node", this.gltf.nodes, channel.target.node);
                 // Ignore animations that have no animation targets.
                 if ((channel.target.path === "weights" /* WEIGHTS */ && !targetNode._numMorphTargets) ||

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 3 - 0
dist/preview release/loaders/babylonjs.loaders.js

@@ -4907,6 +4907,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
                 var _this = this;
+                if (channel.target.node == undefined) {
+                    return Promise.resolve();
+                }
                 var targetNode = ArrayItem.Get(context + "/target/node", this.gltf.nodes, channel.target.node);
                 // Ignore animations that have no animation targets.
                 if ((channel.target.path === "weights" /* WEIGHTS */ && !targetNode._numMorphTargets) ||

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


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

@@ -924,7 +924,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1558,20 +1558,6 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -985,14 +985,13 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
-    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1663,22 +1662,6 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
-declare module 'babylonjs-viewer/optimizer/custom/extended' {
-    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

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

@@ -13,6 +13,8 @@
   - webXRExperienceHelper to setup a default XR experience ([TrevorDev](https://github.com/TrevorDev))
   - WebXREnterExitUI and WebXRManagedOutputCanvas classes to configure the XR experience ([TrevorDev](https://github.com/TrevorDev))
   - WebXRInput manage controllers for the XR experience ([TrevorDev](https://github.com/TrevorDev))
+- GUI:
+  - Added new [ImageBasedSlider](http://doc.babylonjs.com/how_to/gui#imagebasedslider) to let users customize sliders using images ([Deltakosh](https://github.com/deltakosh))
 
 ## Updates
 

+ 20 - 3
gui/src/2D/controls/baseSlider.ts

@@ -13,6 +13,7 @@ export class BaseSlider extends Control {
     private _isVertical = false;
     protected _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
     private _isThumbClamped = false;
+    protected _displayThumb = true;
 
     // Shared rendering info
     protected _effectiveBarOffset = 0;
@@ -27,6 +28,20 @@ export class BaseSlider extends Control {
     /** Observable raised when the sldier value changes */
     public onValueChangedObservable = new Observable<number>();
 
+    /** Gets or sets a boolean indicating if the thumb must be rendered */
+    public get displayThumb(): boolean {
+        return this._displayThumb;
+    }
+
+    public set displayThumb(value: boolean) {
+        if (this._displayThumb === value) {
+            return;
+        }
+
+        this._displayThumb = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
     public get barOffset(): string | number {
         return this._barOffset.toString(this._host);
@@ -200,7 +215,9 @@ export class BaseSlider extends Control {
         this._backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
         this._effectiveThumbThickness = this._getThumbThickness(type);
 
-        this._backgroundBoxLength -= this._effectiveThumbThickness;
+        if (this.displayThumb) {
+            this._backgroundBoxLength -= this._effectiveThumbThickness;
+        }
         //throw error when height is less than width for vertical slider
         if ((this.isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
             console.error("Height should be greater than width");
@@ -217,7 +234,7 @@ export class BaseSlider extends Control {
 
         if (this.isVertical) {
             this._renderLeft += this._effectiveBarOffset;
-            if (!this.isThumbClamped) {
+            if (!this.isThumbClamped && this.displayThumb) {
                 this._renderTop += (this._effectiveThumbThickness / 2);
             }
 
@@ -227,7 +244,7 @@ export class BaseSlider extends Control {
         }
         else {
             this._renderTop += this._effectiveBarOffset;
-            if (!this.isThumbClamped) {
+            if (!this.isThumbClamped && this.displayThumb) {
                 this._renderLeft += (this._effectiveThumbThickness / 2);
             }
             this._renderHeight = this._backgroundBoxThickness;

+ 23 - 7
gui/src/2D/controls/imageBasedSlider.ts

@@ -12,6 +12,19 @@ export class ImageBasedSlider extends BaseSlider {
 
     private _tempMeasure = new Measure(0, 0, 0, 0);
 
+    public get displayThumb(): boolean {
+        return this._displayThumb && this.thumbImage != null;
+    }
+
+    public set displayThumb(value: boolean) {
+        if (this._displayThumb === value) {
+            return;
+        }
+
+        this._displayThumb = value;
+        this._markAsDirty();
+    }
+
     /**
      * Gets or sets the image used to render the background
      */
@@ -103,13 +116,12 @@ export class ImageBasedSlider extends BaseSlider {
             // Background
             if (this._backgroundImage) {
                 this._tempMeasure.copyFromFloats(left, top, width, height);
-                if (this.isThumbClamped) {
+                if (this.isThumbClamped && this.displayThumb) {
                     if (this.isVertical) {
                         this._tempMeasure.height += this._effectiveThumbThickness;
                     } else {
                         this._tempMeasure.width += this._effectiveThumbThickness;
                     }
-
                 }
                 this._backgroundImage._draw(this._tempMeasure, context);
             }
@@ -117,20 +129,24 @@ export class ImageBasedSlider extends BaseSlider {
             // Bar
             if (this._valueBarImage) {
                 if (this.isVertical) {
-                    this._tempMeasure.copyFromFloats(left, top + thumbPosition, width, height - thumbPosition);
-                    if (this.isThumbClamped) {
-                        this._tempMeasure.copyFromFloats(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
+                    if (this.isThumbClamped && this.displayThumb) {
+                        this._tempMeasure.copyFromFloats(left, top + thumbPosition, width, height - thumbPosition + this._effectiveThumbThickness);
                     } else {
                         this._tempMeasure.copyFromFloats(left, top + thumbPosition, width, height - thumbPosition);
                     }
                 } else {
-                    this._tempMeasure.copyFromFloats(left, top, thumbPosition + this._effectiveThumbThickness / 2, height);
+                    if (this.isThumbClamped && this.displayThumb) {
+                        this._tempMeasure.copyFromFloats(left, top, thumbPosition + this._effectiveThumbThickness / 2, height);
+                    }
+                    else {
+                        this._tempMeasure.copyFromFloats(left, top, thumbPosition, height);
+                    }
                 }
                 this._valueBarImage._draw(this._tempMeasure, context);
             }
 
             // Thumb
-            if (this._thumbImage) {
+            if (this.displayThumb) {
                 if (this.isVertical) {
                     this._tempMeasure.copyFromFloats(left - this._effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, this._effectiveThumbThickness);
                 } else {

+ 1 - 16
gui/src/2D/controls/slider.ts

@@ -8,21 +8,6 @@ export class Slider extends BaseSlider {
     private _background = "black";
     private _borderColor = "white";
     private _isThumbCircle = false;
-    private _displayThumb = true;
-
-    /** Gets or sets a boolean indicating if the thumb must be rendered */
-    public get displayThumb(): boolean {
-        return this._displayThumb;
-    }
-
-    public set displayThumb(value: boolean) {
-        if (this._displayThumb === value) {
-            return;
-        }
-
-        this._displayThumb = value;
-        this._markAsDirty();
-    }
 
     /** Gets or sets border color */
     public get borderColor(): string {
@@ -166,7 +151,7 @@ export class Slider extends BaseSlider {
                         context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
                     }
                     else {
-                        context.fillRect(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
+                        context.fillRect(left, top + thumbPosition, width, height - thumbPosition + this._effectiveThumbThickness);
                     }
                 }
                 else {

二进制
tests/validation/ReferenceImages/Sliders.png


+ 5 - 0
tests/validation/config.json

@@ -2,6 +2,11 @@
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "tests": [
     {
+      "title": "Sliders",
+      "playgroundId": "#HATGQZ#3",
+      "referenceImage": "Sliders.png"
+    },
+    {
       "title": "Pointers",
       "playgroundId": "#1GLEJK#5",
       "referenceImage": "pointers.png",