David Catuhe 5 years ago
parent
commit
a1fbd17876
53 changed files with 7182 additions and 3376 deletions
  1. 151 0
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 220 23
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 305 0
      dist/preview release/babylon.module.d.ts
  6. 151 0
      dist/preview release/documentation.d.ts
  7. 3 3
      dist/preview release/gui/babylon.gui.js
  8. 8 8
      dist/preview release/inspector/babylon.inspector.bundle.js
  9. 2889 1531
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  10. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  11. 72 18
      dist/preview release/inspector/babylon.inspector.d.ts
  12. 144 36
      dist/preview release/inspector/babylon.inspector.module.d.ts
  13. 3 3
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  14. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.js
  15. 3 3
      dist/preview release/loaders/babylonjs.loaders.js
  16. 3 3
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  17. 3 3
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  18. 3 3
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  19. 3 3
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  20. 3 3
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  21. 3 3
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  22. 3 3
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  23. 3 3
      dist/preview release/materialsLibrary/babylon.mixMaterial.js
  24. 3 3
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  25. 3 3
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  26. 3 3
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  27. 3 3
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  28. 3 3
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  29. 3 3
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  30. 3 3
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  31. 3 3
      dist/preview release/materialsLibrary/babylonjs.materials.js
  32. 7 7
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  33. 2803 1630
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  34. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  35. 3 3
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js
  36. 3 3
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js
  37. 3 3
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  38. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js
  39. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js
  40. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js
  41. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js
  42. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js
  43. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js
  44. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js
  45. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js
  46. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js
  47. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js
  48. 3 3
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  49. 3 3
      dist/preview release/serializers/babylon.glTF2Serializer.js
  50. 3 3
      dist/preview release/serializers/babylonjs.serializers.js
  51. 305 0
      dist/preview release/viewer/babylon.module.d.ts
  52. 11 7
      dist/preview release/viewer/babylon.viewer.js
  53. 4 4
      dist/preview release/viewer/babylon.viewer.max.js

+ 151 - 0
dist/preview release/babylon.d.ts

@@ -47881,6 +47881,157 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
+declare module BABYLON {
+    /**
      * The options container for the teleportation module
      */
     export interface IWebXRTeleportationOptions {

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


+ 220 - 23
dist/preview release/babylon.max.js

@@ -142688,6 +142688,207 @@ var TGATools = /** @class */ (function () {
 
 /***/ }),
 
+/***/ "./Misc/timer.ts":
+/*!***********************!*\
+  !*** ./Misc/timer.ts ***!
+  \***********************/
+/*! exports provided: TimerState, setAndStartTimer, AdvancedTimer */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimerState", function() { return TimerState; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setAndStartTimer", function() { return setAndStartTimer; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedTimer", function() { return AdvancedTimer; });
+/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
+
+/**
+ * The current state of the timer
+ */
+var TimerState;
+(function (TimerState) {
+    /**
+     * Timer initialized, not yet started
+     */
+    TimerState[TimerState["INIT"] = 0] = "INIT";
+    /**
+     * Timer started and counting
+     */
+    TimerState[TimerState["STARTED"] = 1] = "STARTED";
+    /**
+     * Timer ended (whether aborted or time reached)
+     */
+    TimerState[TimerState["ENDED"] = 2] = "ENDED";
+})(TimerState || (TimerState = {}));
+/**
+ * A simple version of the timer. Will take options and start the timer immediately after calling it
+ *
+ * @param options options with which to initialize this timer
+ */
+function setAndStartTimer(options) {
+    var _a;
+    var timer = 0;
+    var startTime = Date.now();
+    options.observableParameters = (_a = options.observableParameters) !== null && _a !== void 0 ? _a : {};
+    var observer = options.contextObservable.add(function (payload) {
+        var now = Date.now();
+        timer = now - startTime;
+        var data = {
+            startTime: startTime,
+            currentTime: now,
+            deltaTime: timer,
+            completeRate: timer / options.timeout,
+            payload: payload
+        };
+        options.onTick && options.onTick(data);
+        if (options.breakCondition && options.breakCondition()) {
+            options.contextObservable.remove(observer);
+            options.onAborted && options.onAborted(data);
+        }
+        if (timer >= options.timeout) {
+            options.contextObservable.remove(observer);
+            options.onEnded && options.onEnded(data);
+        }
+    }, options.observableParameters.mask, options.observableParameters.insertFirst, options.observableParameters.scope);
+    return observer;
+}
+/**
+ * An advanced implementation of a timer class
+ */
+var AdvancedTimer = /** @class */ (function () {
+    /**
+     * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+     * @param options construction options for this advanced timer
+     */
+    function AdvancedTimer(options) {
+        var _this = this;
+        var _a, _b;
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        this.onEachCountObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        this.onTimerAbortedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        this.onTimerEndedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
+        /**
+         * Will trigger when the timer state has changed
+         */
+        this.onStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
+        this._observer = null;
+        this._breakOnNextTick = false;
+        this._tick = function (payload) {
+            var now = Date.now();
+            _this._timer = now - _this._startTime;
+            var data = {
+                startTime: _this._startTime,
+                currentTime: now,
+                deltaTime: _this._timer,
+                completeRate: _this._timer / _this._timeToEnd,
+                payload: payload
+            };
+            var shouldBreak = _this._breakOnNextTick || _this._breakCondition(data);
+            if (shouldBreak || _this._timer >= _this._timeToEnd) {
+                _this._stop(data, shouldBreak);
+            }
+            else {
+                _this.onEachCountObservable.notifyObservers(data);
+            }
+        };
+        this._setState(TimerState.INIT);
+        this._contextObservable = options.contextObservable;
+        this._observableParameters = (_a = options.observableParameters) !== null && _a !== void 0 ? _a : {};
+        this._breakCondition = (_b = options.breakCondition) !== null && _b !== void 0 ? _b : (function () { return false; });
+        if (options.onEnded) {
+            this.onTimerEndedObservable.add(options.onEnded);
+        }
+        if (options.onTick) {
+            this.onEachCountObservable.add(options.onTick);
+        }
+        if (options.onAborted) {
+            this.onTimerAbortedObservable.add(options.onAborted);
+        }
+    }
+    Object.defineProperty(AdvancedTimer.prototype, "breakCondition", {
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set: function (predicate) {
+            this._breakCondition = predicate;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * Reset ALL associated observables in this advanced timer
+     */
+    AdvancedTimer.prototype.clearObservables = function () {
+        this.onEachCountObservable.clear();
+        this.onTimerAbortedObservable.clear();
+        this.onTimerEndedObservable.clear();
+        this.onStateChangedObservable.clear();
+    };
+    /**
+     * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+     *
+     * @param timeToEnd how much time to measure until timer ended
+     */
+    AdvancedTimer.prototype.start = function (timeToEnd) {
+        if (timeToEnd === void 0) { timeToEnd = this._timeToEnd; }
+        if (this._state === TimerState.STARTED) {
+            throw new Error('Timer already started. Please stop it before starting again');
+        }
+        this._timeToEnd = timeToEnd;
+        this._startTime = Date.now();
+        this._timer = 0;
+        this._observer = this._contextObservable.add(this._tick, this._observableParameters.mask, this._observableParameters.insertFirst, this._observableParameters.scope);
+        this._setState(TimerState.STARTED);
+    };
+    /**
+     * Will force a stop on the next tick.
+     */
+    AdvancedTimer.prototype.stop = function () {
+        if (this._state !== TimerState.STARTED) {
+            return;
+        }
+        this._breakOnNextTick = true;
+    };
+    /**
+     * Dispose this timer, clearing all resources
+     */
+    AdvancedTimer.prototype.dispose = function () {
+        if (this._observer) {
+            this._contextObservable.remove(this._observer);
+        }
+        this.clearObservables();
+    };
+    AdvancedTimer.prototype._setState = function (newState) {
+        this._state = newState;
+        this.onStateChangedObservable.notifyObservers(this._state);
+    };
+    AdvancedTimer.prototype._stop = function (data, aborted) {
+        if (aborted === void 0) { aborted = false; }
+        this._contextObservable.remove(this._observer);
+        this._setState(TimerState.ENDED);
+        if (aborted) {
+            this.onTimerAbortedObservable.notifyObservers(data);
+        }
+        else {
+            this.onTimerEndedObservable.notifyObservers(data);
+        }
+    };
+    return AdvancedTimer;
+}());
+
+
+
+/***/ }),
+
 /***/ "./Misc/timingTools.ts":
 /*!*****************************!*\
   !*** ./Misc/timingTools.ts ***!
@@ -181741,6 +181942,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
 /* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
 /* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
+/* harmony import */ var _Misc_timer__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../Misc/timer */ "./Misc/timer.ts");
+
 
 
 
@@ -181846,20 +182049,15 @@ var WebXRMotionControllerTeleportation = /** @class */ (function (_super) {
                                         _this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
                                         controllerData.teleportationState.baseRotation = _this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
                                         controllerData.teleportationState.currentRotation = 0;
-                                        var timeToSelect_1 = _this._options.timeToTeleport || 3000;
-                                        var timer_1 = 0;
-                                        var observer_1 = _this._xrSessionManager.onXRFrameObservable.add(function () {
-                                            if (!mainComponent_1.pressed) {
-                                                _this._xrSessionManager.onXRFrameObservable.remove(observer_1);
-                                                return;
-                                            }
-                                            timer_1 += _this._xrSessionManager.scene.getEngine().getDeltaTime();
-                                            if (timer_1 >= timeToSelect_1 && _this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
-                                                _this._teleportForward(xrController.uniqueId);
-                                            }
-                                            // failsafe
-                                            if (timer_1 >= timeToSelect_1) {
-                                                _this._xrSessionManager.onXRFrameObservable.remove(observer_1);
+                                        var timeToSelect = _this._options.timeToTeleport || 3000;
+                                        Object(_Misc_timer__WEBPACK_IMPORTED_MODULE_19__["setAndStartTimer"])({
+                                            timeout: timeToSelect,
+                                            contextObservable: _this._xrSessionManager.onXRFrameObservable,
+                                            breakCondition: function () { return !mainComponent_1.pressed; },
+                                            onEnded: function () {
+                                                if (_this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
+                                                    _this._teleportForward(xrController.uniqueId);
+                                                }
                                             }
                                         });
                                     }
@@ -181945,15 +182143,14 @@ var WebXRMotionControllerTeleportation = /** @class */ (function (_super) {
                         _this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
                         controllerData.teleportationState.baseRotation = _this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
                         controllerData.teleportationState.currentRotation = 0;
-                        var timeToSelect_2 = _this._options.timeToTeleport || 3000;
-                        var timer_2 = 0;
-                        var observer_2 = _this._xrSessionManager.onXRFrameObservable.add(function () {
-                            timer_2 += _this._xrSessionManager.scene.getEngine().getDeltaTime();
-                            if (timer_2 >= timeToSelect_2 && _this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
-                                _this._teleportForward(xrController.uniqueId);
-                            }
-                            if (timer_2 >= timeToSelect_2) {
-                                _this._xrSessionManager.onXRFrameObservable.remove(observer_2);
+                        var timeToSelect = _this._options.timeToTeleport || 3000;
+                        Object(_Misc_timer__WEBPACK_IMPORTED_MODULE_19__["setAndStartTimer"])({
+                            timeout: timeToSelect,
+                            contextObservable: _this._xrSessionManager.onXRFrameObservable,
+                            onEnded: function () {
+                                if (_this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
+                                    _this._teleportForward(xrController.uniqueId);
+                                }
                             }
                         });
                     }

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


+ 305 - 0
dist/preview release/babylon.module.d.ts

@@ -49653,6 +49653,160 @@ declare module "babylonjs/Meshes/Builders/linesBuilder" {
         }, scene?: Nullable<Scene>): LinesMesh;
     }
 }
+declare module "babylonjs/Misc/timer" {
+    import { Observable, Observer } from "babylonjs/Misc/observable";
+    import { Nullable } from "babylonjs/types";
+    import { IDisposable } from "babylonjs/scene";
+    /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
 declare module "babylonjs/XR/features/WebXRControllerTeleportation" {
     import { IWebXRFeature } from "babylonjs/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
@@ -125176,6 +125330,157 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
+declare module BABYLON {
+    /**
      * The options container for the teleportation module
      */
     export interface IWebXRTeleportationOptions {

+ 151 - 0
dist/preview release/documentation.d.ts

@@ -47881,6 +47881,157 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
+declare module BABYLON {
+    /**
      * The options container for the teleportation module
      */
     export interface IWebXRTeleportationOptions {

+ 3 - 3
dist/preview release/gui/babylon.gui.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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


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


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


+ 72 - 18
dist/preview release/inspector/babylon.inspector.d.ts

@@ -519,9 +519,11 @@ declare module INSPECTOR {
         type: string;
         index: string;
         selected: boolean;
+        selectControlPoint: (id: string) => void;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -531,15 +533,24 @@ declare module INSPECTOR {
         rightControlPoint: BABYLON.Vector2 | null;
         leftControlPoint: BABYLON.Vector2 | null;
         id: string;
+        selected: boolean;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     interface IKeyframeSvgPointProps {
         keyframePoint: BABYLON.Vector2;
         leftControlPoint: BABYLON.Vector2 | null;
         rightControlPoint: BABYLON.Vector2 | null;
         id: string;
+        selected: boolean;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -549,6 +560,8 @@ declare module INSPECTOR {
         updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
         scale: number;
         viewBoxScale: number;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
     }
     export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
         private _active;
@@ -625,6 +638,8 @@ declare module INSPECTOR {
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
+        brokeTangents: () => void;
+        brokenMode: boolean;
         currentValue: number;
         currentFrame: number;
     }
@@ -660,7 +675,9 @@ declare module INSPECTOR {
         currentValue: number;
         frameAxisLength: ICanvasAxis[];
         valueAxisLength: ICanvasAxis[];
-        flatTangent: boolean;
+        isFlatTangentMode: boolean;
+        isTangentMode: boolean;
+        isBrokenMode: boolean;
         scale: number;
         playheadOffset: number;
         notification: string;
@@ -679,35 +696,60 @@ declare module INSPECTOR {
         private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
-        resetPlayheadOffset(): void;
+        /**
+        * Notifications
+        * To add notification we set the state and clear to make the notification bar hide.
+        */
+        clearNotification(): void;
+        /**
+        * Zoom and Scroll
+        * This section handles zoom and scroll
+        * of the graph area.
+        */
+        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
+        resetPlayheadOffset(): void;
+        /**
+        * Add New BABYLON.Animation
+        * This section handles events from AnimationCreation.
+        */
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        getAnimationTypeofChange(selected: string): number;
         addAnimation(): void;
-        clearNotification(): void;
+        /**
+        * Keyframe Manipulation
+        * This section handles events from SvgDraggableArea.
+        */
+        selectKeyframe(id: string): void;
+        selectedControlPoint(type: string, id: string): void;
+        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
+        /**
+        * Actions
+        * This section handles events from GraphActionsBar.
+        */
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setFlatTangent(): void;
+        setTangentMode(): void;
+        setBrokenMode(): void;
         addKeyframeClick(): void;
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
+        /**
+        * Curve Rendering Functions
+        * This section handles how to render curves.
+        */
         getAnimationProperties(animation: BABYLON.Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
-        getPathData(animation: BABYLON.Animation): string;
-        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
-        curvePathFlat(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, dataType: number): string;
-        curvePathWithTangents(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, type: number): string;
-        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, easingFunction: BABYLON.EasingFunction): string;
-        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
         linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: BABYLON.Vector2, index: number): void;
-        setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
-        isAnimationPlaying(): void;
-        selectAnimation(animation: BABYLON.Animation): void;
+        getPathData(animation: BABYLON.Animation): string;
         getAnimationData(animation: BABYLON.Animation): {
             loopMode: number | undefined;
             name: string;
@@ -717,13 +759,25 @@ declare module INSPECTOR {
             framesPerSecond: number;
             highestFrame: number;
             serialized: any;
-            usesTangents: BABYLON.IAnimationKey | undefined;
+            usesTangents: boolean;
         };
-        getAnimationTypeofChange(selected: string): number;
+        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
+        curvePathFlat(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, dataType: number): string;
+        curvePathWithTangents(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, type: number): string;
+        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, easingFunction: BABYLON.EasingFunction): string;
+        setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
+        /**
+        * Core functions
+        * This section handles main Curve Editor Functions.
+        */
+        selectAnimation(animation: BABYLON.Animation): void;
+        isAnimationPlaying(): void;
+        /**
+        * Timeline
+        * This section controls the timeline.
+        */
         changeCurrentFrame(frame: number): void;
-        setFlatTangent(): void;
-        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         render(): JSX.Element;
     }
 }

+ 144 - 36
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -590,9 +590,11 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         type: string;
         index: string;
         selected: boolean;
+        selectControlPoint: (id: string) => void;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -604,15 +606,24 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         rightControlPoint: Vector2 | null;
         leftControlPoint: Vector2 | null;
         id: string;
+        selected: boolean;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     interface IKeyframeSvgPointProps {
         keyframePoint: Vector2;
         leftControlPoint: Vector2 | null;
         rightControlPoint: Vector2 | null;
         id: string;
+        selected: boolean;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -625,6 +636,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
         scale: number;
         viewBoxScale: number;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
     }
     export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
         private _active;
@@ -706,6 +719,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
+        brokeTangents: () => void;
+        brokenMode: boolean;
         currentValue: number;
         currentFrame: number;
     }
@@ -749,7 +764,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         currentValue: number;
         frameAxisLength: ICanvasAxis[];
         valueAxisLength: ICanvasAxis[];
-        flatTangent: boolean;
+        isFlatTangentMode: boolean;
+        isTangentMode: boolean;
+        isBrokenMode: boolean;
         scale: number;
         playheadOffset: number;
         notification: string;
@@ -768,35 +785,60 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
-        resetPlayheadOffset(): void;
+        /**
+        * Notifications
+        * To add notification we set the state and clear to make the notification bar hide.
+        */
+        clearNotification(): void;
+        /**
+        * Zoom and Scroll
+        * This section handles zoom and scroll
+        * of the graph area.
+        */
+        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
+        resetPlayheadOffset(): void;
+        /**
+        * Add New Animation
+        * This section handles events from AnimationCreation.
+        */
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        getAnimationTypeofChange(selected: string): number;
         addAnimation(): void;
-        clearNotification(): void;
+        /**
+        * Keyframe Manipulation
+        * This section handles events from SvgDraggableArea.
+        */
+        selectKeyframe(id: string): void;
+        selectedControlPoint(type: string, id: string): void;
+        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
+        /**
+        * Actions
+        * This section handles events from GraphActionsBar.
+        */
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setFlatTangent(): void;
+        setTangentMode(): void;
+        setBrokenMode(): void;
         addKeyframeClick(): void;
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: Vector2, index: number): void;
+        /**
+        * Curve Rendering Functions
+        * This section handles how to render curves.
+        */
         getAnimationProperties(animation: Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
-        getPathData(animation: Animation): string;
-        drawAllFrames(initialKey: IAnimationKey, endKey: IAnimationKey, easingFunction: EasingFunction): void;
-        curvePathFlat(keyframes: IAnimationKey[], data: string, middle: number, dataType: number): string;
-        curvePathWithTangents(keyframes: IAnimationKey[], data: string, middle: number, type: number): string;
-        curvePath(keyframes: IAnimationKey[], data: string, middle: number, easingFunction: EasingFunction): string;
-        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
         linearInterpolation(keyframes: IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: Vector2, index: number): void;
-        setKeyframePoint(controlPoints: Vector2[], index: number, keyframesCount: number): void;
-        isAnimationPlaying(): void;
-        selectAnimation(animation: Animation): void;
+        getPathData(animation: Animation): string;
         getAnimationData(animation: Animation): {
             loopMode: number | undefined;
             name: string;
@@ -806,13 +848,25 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
             framesPerSecond: number;
             highestFrame: number;
             serialized: any;
-            usesTangents: IAnimationKey | undefined;
+            usesTangents: boolean;
         };
-        getAnimationTypeofChange(selected: string): number;
+        drawAllFrames(initialKey: IAnimationKey, endKey: IAnimationKey, easingFunction: EasingFunction): void;
+        curvePathFlat(keyframes: IAnimationKey[], data: string, middle: number, dataType: number): string;
+        curvePathWithTangents(keyframes: IAnimationKey[], data: string, middle: number, type: number): string;
+        curvePath(keyframes: IAnimationKey[], data: string, middle: number, easingFunction: EasingFunction): string;
+        setKeyframePoint(controlPoints: Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: Vector2, p1: Vector2, u: number, p2: Vector2, v: number, p3: Vector2): Vector2[] | undefined;
+        /**
+        * Core functions
+        * This section handles main Curve Editor Functions.
+        */
+        selectAnimation(animation: Animation): void;
+        isAnimationPlaying(): void;
+        /**
+        * Timeline
+        * This section controls the timeline.
+        */
         changeCurrentFrame(frame: number): void;
-        setFlatTangent(): void;
-        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         render(): JSX.Element;
     }
 }
@@ -3729,9 +3783,11 @@ declare module INSPECTOR {
         type: string;
         index: string;
         selected: boolean;
+        selectControlPoint: (id: string) => void;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -3741,15 +3797,24 @@ declare module INSPECTOR {
         rightControlPoint: BABYLON.Vector2 | null;
         leftControlPoint: BABYLON.Vector2 | null;
         id: string;
+        selected: boolean;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     interface IKeyframeSvgPointProps {
         keyframePoint: BABYLON.Vector2;
         leftControlPoint: BABYLON.Vector2 | null;
         rightControlPoint: BABYLON.Vector2 | null;
         id: string;
+        selected: boolean;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
+        isLeftActive: boolean;
+        isRightActive: boolean;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
+        select(): void;
         render(): JSX.Element;
     }
 }
@@ -3759,6 +3824,8 @@ declare module INSPECTOR {
         updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
         scale: number;
         viewBoxScale: number;
+        selectKeyframe: (id: string) => void;
+        selectedControlPoint: (type: string, id: string) => void;
     }
     export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
         private _active;
@@ -3835,6 +3902,8 @@ declare module INSPECTOR {
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
+        brokeTangents: () => void;
+        brokenMode: boolean;
         currentValue: number;
         currentFrame: number;
     }
@@ -3870,7 +3939,9 @@ declare module INSPECTOR {
         currentValue: number;
         frameAxisLength: ICanvasAxis[];
         valueAxisLength: ICanvasAxis[];
-        flatTangent: boolean;
+        isFlatTangentMode: boolean;
+        isTangentMode: boolean;
+        isBrokenMode: boolean;
         scale: number;
         playheadOffset: number;
         notification: string;
@@ -3889,35 +3960,60 @@ declare module INSPECTOR {
         private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
-        resetPlayheadOffset(): void;
+        /**
+        * Notifications
+        * To add notification we set the state and clear to make the notification bar hide.
+        */
+        clearNotification(): void;
+        /**
+        * Zoom and Scroll
+        * This section handles zoom and scroll
+        * of the graph area.
+        */
+        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
+        resetPlayheadOffset(): void;
+        /**
+        * Add New BABYLON.Animation
+        * This section handles events from AnimationCreation.
+        */
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
-        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        getAnimationTypeofChange(selected: string): number;
         addAnimation(): void;
-        clearNotification(): void;
+        /**
+        * Keyframe Manipulation
+        * This section handles events from SvgDraggableArea.
+        */
+        selectKeyframe(id: string): void;
+        selectedControlPoint(type: string, id: string): void;
+        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
+        /**
+        * Actions
+        * This section handles events from GraphActionsBar.
+        */
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setFlatTangent(): void;
+        setTangentMode(): void;
+        setBrokenMode(): void;
         addKeyframeClick(): void;
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
+        /**
+        * Curve Rendering Functions
+        * This section handles how to render curves.
+        */
         getAnimationProperties(animation: BABYLON.Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
-        getPathData(animation: BABYLON.Animation): string;
-        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
-        curvePathFlat(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, dataType: number): string;
-        curvePathWithTangents(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, type: number): string;
-        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, easingFunction: BABYLON.EasingFunction): string;
-        renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number): void;
         linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: BABYLON.Vector2, index: number): void;
-        setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
-        isAnimationPlaying(): void;
-        selectAnimation(animation: BABYLON.Animation): void;
+        getPathData(animation: BABYLON.Animation): string;
         getAnimationData(animation: BABYLON.Animation): {
             loopMode: number | undefined;
             name: string;
@@ -3927,13 +4023,25 @@ declare module INSPECTOR {
             framesPerSecond: number;
             highestFrame: number;
             serialized: any;
-            usesTangents: BABYLON.IAnimationKey | undefined;
+            usesTangents: boolean;
         };
-        getAnimationTypeofChange(selected: string): number;
+        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
+        curvePathFlat(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, dataType: number): string;
+        curvePathWithTangents(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, type: number): string;
+        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, middle: number, easingFunction: BABYLON.EasingFunction): string;
+        setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
+        /**
+        * Core functions
+        * This section handles main Curve Editor Functions.
+        */
+        selectAnimation(animation: BABYLON.Animation): void;
+        isAnimationPlaying(): void;
+        /**
+        * Timeline
+        * This section controls the timeline.
+        */
         changeCurrentFrame(frame: number): void;
-        setFlatTangent(): void;
-        zoom(e: React.WheelEvent<HTMLDivElement>): void;
         render(): JSX.Element;
     }
 }

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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


File diff suppressed because it is too large
+ 2803 - 1630
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 3 - 3
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/serializers/babylonjs.serializers.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** E:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 305 - 0
dist/preview release/viewer/babylon.module.d.ts

@@ -49653,6 +49653,160 @@ declare module "babylonjs/Meshes/Builders/linesBuilder" {
         }, scene?: Nullable<Scene>): LinesMesh;
     }
 }
+declare module "babylonjs/Misc/timer" {
+    import { Observable, Observer } from "babylonjs/Misc/observable";
+    import { Nullable } from "babylonjs/types";
+    import { IDisposable } from "babylonjs/scene";
+    /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
 declare module "babylonjs/XR/features/WebXRControllerTeleportation" {
     import { IWebXRFeature } from "babylonjs/XR/webXRFeaturesManager";
     import { WebXRSessionManager } from "babylonjs/XR/webXRSessionManager";
@@ -125176,6 +125330,157 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Construction options for a timer
+     */
+    export interface ITimerOptions<T> {
+        /**
+         * Time-to-end
+         */
+        timeout: number;
+        /**
+         * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.
+         * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if
+         * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time
+         */
+        contextObservable: Observable<T>;
+        /**
+         * Optional parameters when adding an observer to the observable
+         */
+        observableParameters?: {
+            mask?: number;
+            insertFirst?: boolean;
+            scope?: any;
+        };
+        /**
+         * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!
+         */
+        breakCondition?: (data?: ITimerData<T>) => boolean;
+        /**
+         * Will be triggered when the time condition has met
+         */
+        onEnded?: (data: ITimerData<any>) => void;
+        /**
+         * Will be triggered when the break condition has met (prematurely ended)
+         */
+        onAborted?: (data: ITimerData<any>) => void;
+        /**
+         * Optional function to execute on each tick (or count)
+         */
+        onTick?: (data: ITimerData<any>) => void;
+    }
+    /**
+     * An interface defining the data sent by the timer
+     */
+    export interface ITimerData<T> {
+        /**
+         * When did it start
+         */
+        startTime: number;
+        /**
+         * Time now
+         */
+        currentTime: number;
+        /**
+         * Time passed since started
+         */
+        deltaTime: number;
+        /**
+         * How much is completed, in [0.0...1.0].
+         * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls
+         */
+        completeRate: number;
+        /**
+         * What the registered observable sent in the last count
+         */
+        payload: T;
+    }
+    /**
+     * The current state of the timer
+     */
+    export enum TimerState {
+        /**
+         * Timer initialized, not yet started
+         */
+        INIT = 0,
+        /**
+         * Timer started and counting
+         */
+        STARTED = 1,
+        /**
+         * Timer ended (whether aborted or time reached)
+         */
+        ENDED = 2
+    }
+    /**
+     * A simple version of the timer. Will take options and start the timer immediately after calling it
+     *
+     * @param options options with which to initialize this timer
+     */
+    export function setAndStartTimer(options: ITimerOptions<any>): Nullable<Observer<any>>;
+    /**
+     * An advanced implementation of a timer class
+     */
+    export class AdvancedTimer<T = any> implements IDisposable {
+        /**
+         * Will notify each time the timer calculates the remaining time
+         */
+        onEachCountObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer was aborted due to the break condition
+         */
+        onTimerAbortedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer ended successfully
+         */
+        onTimerEndedObservable: Observable<ITimerData<T>>;
+        /**
+         * Will trigger when the timer state has changed
+         */
+        onStateChangedObservable: Observable<TimerState>;
+        private _observer;
+        private _contextObservable;
+        private _observableParameters;
+        private _startTime;
+        private _timer;
+        private _state;
+        private _breakCondition;
+        private _timeToEnd;
+        private _breakOnNextTick;
+        /**
+         * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.
+         * @param options construction options for this advanced timer
+         */
+        constructor(options: ITimerOptions<T>);
+        /**
+         * set a breaking condition for this timer. Default is to never break during count
+         * @param predicate the new break condition. Returns true to break, false otherwise
+         */
+        set breakCondition(predicate: (data: ITimerData<T>) => boolean);
+        /**
+         * Reset ALL associated observables in this advanced timer
+         */
+        clearObservables(): void;
+        /**
+         * Will start a new iteration of this timer. Only one instance of this timer can run at a time.
+         *
+         * @param timeToEnd how much time to measure until timer ended
+         */
+        start(timeToEnd?: number): void;
+        /**
+         * Will force a stop on the next tick.
+         */
+        stop(): void;
+        /**
+         * Dispose this timer, clearing all resources
+         */
+        dispose(): void;
+        private _setState;
+        private _tick;
+        private _stop;
+    }
+}
+declare module BABYLON {
+    /**
      * The options container for the teleportation module
      */
     export interface IWebXRTeleportationOptions {

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


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