Browse Source

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into nme-particle

Popov72 5 years ago
parent
commit
56125ccb68
41 changed files with 2680 additions and 373 deletions
  1. 70 4
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 135 9
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 142 8
      dist/preview release/babylon.module.d.ts
  6. 70 4
      dist/preview release/documentation.d.ts
  7. 48 48
      dist/preview release/gui/babylon.gui.js
  8. 1 1
      dist/preview release/gui/babylon.gui.js.map
  9. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  10. 787 116
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  11. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  12. 143 13
      dist/preview release/inspector/babylon.inspector.d.ts
  13. 313 26
      dist/preview release/inspector/babylon.inspector.module.d.ts
  14. 1 1
      dist/preview release/packagesSizeBaseLine.json
  15. 142 8
      dist/preview release/viewer/babylon.module.d.ts
  16. 6 6
      dist/preview release/viewer/babylon.viewer.js
  17. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  18. 2 2
      dist/preview release/what's new.md
  19. 9 1
      inspector/src/components/actionTabs/lines/floatLineComponent.tsx
  20. 1 1
      inspector/src/components/actionTabs/lines/sliderLineComponent.tsx
  21. 22 0
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  22. 109 93
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx
  23. 94 1
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss
  24. 24 0
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/playhead.tsx
  25. 116 0
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/timeline.tsx
  26. 2 0
      inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx
  27. 55 0
      inspector/src/components/actionTabs/tabs/propertyGrids/sprites/spriteManagerPropertyGridComponent.tsx
  28. 84 0
      inspector/src/components/actionTabs/tabs/propertyGrids/sprites/spritePropertyGridComponent.tsx
  29. 30 0
      inspector/src/components/sceneExplorer/entities/spriteManagerTreeItemComponent.tsx
  30. 30 0
      inspector/src/components/sceneExplorer/entities/spriteTreeItemComponent.tsx
  31. 25 1
      inspector/src/components/sceneExplorer/sceneExplorer.scss
  32. 15 0
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  33. 13 8
      inspector/src/components/sceneExplorer/treeItemComponent.tsx
  34. 12 0
      inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx
  35. 1 1
      src/Bones/skeleton.ts
  36. 7 0
      src/Materials/standardMaterial.ts
  37. 2 1
      src/Meshes/mesh.ts
  38. 11 1
      src/Shaders/default.fragment.fx
  39. 64 5
      src/Sprites/sprite.ts
  40. 83 3
      src/Sprites/spriteManager.ts
  41. 1 1
      src/node.ts

+ 70 - 4
dist/preview release/babylon.d.ts

@@ -10026,6 +10026,10 @@ declare module BABYLON {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -10035,6 +10039,10 @@ declare module BABYLON {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -10044,6 +10052,14 @@ declare module BABYLON {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -10114,6 +10130,23 @@ declare module BABYLON {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -10146,6 +10179,11 @@ declare module BABYLON {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -18137,7 +18175,7 @@ declare module BABYLON {
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -18155,13 +18193,13 @@ declare module BABYLON {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -18201,6 +18239,14 @@ declare module BABYLON {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -18209,6 +18255,23 @@ declare module BABYLON {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -26892,6 +26955,9 @@ declare module BABYLON {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;

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


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


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


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

@@ -10224,6 +10224,10 @@ declare module "babylonjs/Sprites/spriteManager" {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -10233,6 +10237,10 @@ declare module "babylonjs/Sprites/spriteManager" {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -10242,6 +10250,14 @@ declare module "babylonjs/Sprites/spriteManager" {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -10312,6 +10328,23 @@ declare module "babylonjs/Sprites/spriteManager" {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -10344,6 +10377,11 @@ declare module "babylonjs/Sprites/spriteManager" {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -18636,11 +18674,13 @@ declare module "babylonjs/Sprites/sprite" {
     import { ISpriteManager } from "babylonjs/Sprites/spriteManager";
     import { Color4 } from "babylonjs/Maths/math.color";
     import { Observable } from "babylonjs/Misc/observable";
+    import { IAnimatable } from "babylonjs/Animations/animatable.interface";
+    import { Animation } from "babylonjs/Animations/animation";
     /**
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -18658,13 +18698,13 @@ declare module "babylonjs/Sprites/sprite" {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -18704,6 +18744,14 @@ declare module "babylonjs/Sprites/sprite" {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -18712,6 +18760,23 @@ declare module "babylonjs/Sprites/sprite" {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -27749,6 +27814,9 @@ declare module "babylonjs/Materials/standardMaterial" {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -86006,6 +86074,10 @@ declare module BABYLON {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -86015,6 +86087,10 @@ declare module BABYLON {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -86024,6 +86100,14 @@ declare module BABYLON {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -86094,6 +86178,23 @@ declare module BABYLON {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -86126,6 +86227,11 @@ declare module BABYLON {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -94117,7 +94223,7 @@ declare module BABYLON {
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -94135,13 +94241,13 @@ declare module BABYLON {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -94181,6 +94287,14 @@ declare module BABYLON {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -94189,6 +94303,23 @@ declare module BABYLON {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -102872,6 +103003,9 @@ declare module BABYLON {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;

+ 70 - 4
dist/preview release/documentation.d.ts

@@ -10026,6 +10026,10 @@ declare module BABYLON {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -10035,6 +10039,10 @@ declare module BABYLON {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -10044,6 +10052,14 @@ declare module BABYLON {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -10114,6 +10130,23 @@ declare module BABYLON {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -10146,6 +10179,11 @@ declare module BABYLON {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -18137,7 +18175,7 @@ declare module BABYLON {
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -18155,13 +18193,13 @@ declare module BABYLON {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -18201,6 +18239,14 @@ declare module BABYLON {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -18209,6 +18255,23 @@ declare module BABYLON {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -26892,6 +26955,9 @@ declare module BABYLON {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;

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

@@ -7,7 +7,7 @@
 		exports["babylonjs-gui"] = factory(require("babylonjs"));
 	else
 		root["BABYLON"] = root["BABYLON"] || {}, root["BABYLON"]["GUI"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -366,7 +366,7 @@ module.exports = g;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
-/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -509,7 +509,7 @@ var AdvancedDynamicTextureInstrumentation = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTexture", function() { return AdvancedDynamicTexture; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _controls_container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls/container */ "./2D/controls/container.ts");
 /* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./2D/style.ts");
@@ -1481,7 +1481,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _textBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./textBlock */ "./2D/controls/textBlock.ts");
 /* harmony import */ var _image__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./image */ "./2D/controls/image.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__);
 
 
@@ -1713,7 +1713,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return Checkbox; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -1896,7 +1896,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPicker", function() { return ColorPicker; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
@@ -3285,7 +3285,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -3700,7 +3700,7 @@ babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredTypes
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control", function() { return Control; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -5626,7 +5626,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplayGrid", function() { return DisplayGrid; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -5859,7 +5859,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -5956,7 +5956,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__);
 
 
@@ -6414,7 +6414,7 @@ babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes[
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Image", function() { return Image; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 
@@ -7341,7 +7341,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputPassword", function() { return InputPassword; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -7380,7 +7380,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputText", function() { return InputText; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8393,7 +8393,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line", function() { return Line; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8664,7 +8664,7 @@ babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registere
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLine", function() { return MultiLine; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _multiLinePoint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../multiLinePoint */ "./2D/multiLinePoint.ts");
@@ -8934,7 +8934,7 @@ babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registe
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RadioButton", function() { return RadioButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -9141,7 +9141,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Rectangle", function() { return Rectangle; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -9291,7 +9291,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _scrollViewerWindow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./scrollViewerWindow */ "./2D/controls/scrollViewers/scrollViewerWindow.ts");
 /* harmony import */ var _sliders_scrollBar__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../sliders/scrollBar */ "./2D/controls/sliders/scrollBar.ts");
 /* harmony import */ var _sliders_imageScrollBar__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../sliders/imageScrollBar */ "./2D/controls/sliders/imageScrollBar.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__);
 
 
@@ -10914,7 +10914,7 @@ var SelectionPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSlider", function() { return BaseSlider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -11244,7 +11244,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../measure */ "./2D/measure.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -11837,7 +11837,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Slider", function() { return Slider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -12092,7 +12092,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel", function() { return StackPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12360,7 +12360,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextWrapping", function() { return TextWrapping; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextBlock", function() { return TextBlock; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12823,7 +12823,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyPropertySet", function() { return KeyPropertySet; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualKeyboard", function() { return VirtualKeyboard; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
 /* harmony import */ var _button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./button */ "./2D/controls/button.ts");
@@ -13212,7 +13212,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2WithInfo", function() { return Vector2WithInfo; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix2D", function() { return Matrix2D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -13437,7 +13437,7 @@ var Matrix2D = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Measure", function() { return Measure; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 var tmpRect = [
@@ -13586,7 +13586,7 @@ var Measure = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLinePoint", function() { return MultiLinePoint; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -13729,7 +13729,7 @@ var MultiLinePoint = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Style", function() { return Style; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -14035,7 +14035,7 @@ var ValueAndUnit = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "XmlLoader", function() { return XmlLoader; });
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -14354,7 +14354,7 @@ var XmlLoader = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractButton3D", function() { return AbstractButton3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14397,7 +14397,7 @@ var AbstractButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Button3D", function() { return Button3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _abstractButton3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractButton3D */ "./3D/controls/abstractButton3D.ts");
 /* harmony import */ var _2D_advancedDynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../2D/advancedDynamicTexture */ "./2D/advancedDynamicTexture.ts");
@@ -14578,7 +14578,7 @@ var Button3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container3D", function() { return Container3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14735,7 +14735,7 @@ var Container3D = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control3D", function() { return Control3D; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _vector3WithInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../vector3WithInfo */ "./3D/vector3WithInfo.ts");
 
@@ -15141,7 +15141,7 @@ var Control3D = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderPanel", function() { return CylinderPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15227,7 +15227,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HolographicButton", function() { return HolographicButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _button3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./button3D */ "./3D/controls/button3D.ts");
-/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _materials_fluentMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/fluentMaterial */ "./3D/materials/fluentMaterial.ts");
 /* harmony import */ var _2D_controls_stackPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../2D/controls/stackPanel */ "./2D/controls/stackPanel.ts");
@@ -15721,7 +15721,7 @@ var MeshButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlanePanel", function() { return PlanePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
@@ -15776,7 +15776,7 @@ var PlanePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScatterPanel", function() { return ScatterPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15903,7 +15903,7 @@ var ScatterPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpherePanel", function() { return SpherePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15989,7 +15989,7 @@ var SpherePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel3D", function() { return StackPanel3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16114,7 +16114,7 @@ var StackPanel3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VolumeBasedPanel", function() { return VolumeBasedPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16305,7 +16305,7 @@ var VolumeBasedPanel = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GUI3DManager", function() { return GUI3DManager; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _controls_container3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls/container3D */ "./3D/controls/container3D.ts");
 
@@ -16572,7 +16572,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterialDefines", function() { return FluentMaterialDefines; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterial", function() { return FluentMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _shaders_fluent_vertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaders/fluent.vertex */ "./3D/materials/shaders/fluent.vertex.ts");
 /* harmony import */ var _shaders_fluent_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaders/fluent.fragment */ "./3D/materials/shaders/fluent.fragment.ts");
@@ -16895,7 +16895,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentPixelShader", function() { return fluentPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentPixelShader';
@@ -16917,7 +16917,7 @@ var fluentPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentVertexShader", function() { return fluentVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentVertexShader';
@@ -16940,7 +16940,7 @@ var fluentVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3WithInfo", function() { return Vector3WithInfo; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -17242,14 +17242,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/perfCounter":
+/***/ "babylonjs/Maths/math.vector":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
 
 /***/ })
 

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


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


File diff suppressed because it is too large
+ 787 - 116
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


+ 143 - 13
dist/preview release/inspector/babylon.inspector.d.ts

@@ -492,6 +492,7 @@ declare module INSPECTOR {
         step?: string;
         digits?: number;
         useEuler?: boolean;
+        min?: number;
     }
     export class FloatLineComponent extends React.Component<IFloatLineComponentProps, {
         value: string;
@@ -512,8 +513,11 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IAnchorSvgPointProps {
-        point: BABYLON.Vector2;
+        control: BABYLON.Vector2;
         anchor: BABYLON.Vector2;
+        active: boolean;
+        type: string;
+        index: string;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -521,8 +525,17 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export interface IKeyframeSvgPoint {
+        keyframePoint: BABYLON.Vector2;
+        rightControlPoint: BABYLON.Vector2 | null;
+        leftControlPoint: BABYLON.Vector2 | null;
+        id: string;
+    }
     interface IKeyframeSvgPointProps {
-        point: BABYLON.Vector2;
+        keyframePoint: BABYLON.Vector2;
+        leftControlPoint: BABYLON.Vector2 | null;
+        rightControlPoint: BABYLON.Vector2 | null;
+        id: string;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
@@ -530,36 +543,103 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISvgDraggableAreaProps {
+        keyframeSvgPoints: IKeyframeSvgPoint[];
+        updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
+    }
+    export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
+        private _active;
+        private _isCurrentPointControl;
+        private _currentPointIndex;
+        private _draggableArea;
+        constructor(props: ISvgDraggableAreaProps);
+        dragStart(e: React.TouchEvent<SVGSVGElement>): void;
+        dragStart(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<SVGSVGElement>): void;
+        drag(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
+        dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        getMousePosition(e: React.TouchEvent<SVGSVGElement>): BABYLON.Vector2 | undefined;
+        getMousePosition(e: React.MouseEvent<SVGSVGElement, MouseEvent>): BABYLON.Vector2 | undefined;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ITimelineProps {
+        keyframes: BABYLON.IAnimationKey[];
+        selected: BABYLON.IAnimationKey;
+        currentFrame: number;
+        onCurrentFrameChange: (frame: number) => void;
+    }
+    export class Timeline extends React.Component<ITimelineProps, {
+        selected: BABYLON.IAnimationKey;
+    }> {
+        readonly _frames: object[];
+        private _scrollable;
+        constructor(props: ITimelineProps);
+        handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        previousKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IPlayheadProps {
+        frame: number;
+    }
+    export class Playhead extends React.Component<IPlayheadProps> {
+        constructor(props: IPlayheadProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface IAnimationCurveEditorComponentProps {
         close: (event: any) => void;
+        playOrPause: () => void;
         title: string;
         animations: BABYLON.Animation[];
         entityName: string;
+        scene: BABYLON.Scene;
+        entity: BABYLON.IAnimatable;
     }
     export class AnimationCurveEditorComponent extends React.Component<IAnimationCurveEditorComponentProps, {
+        animations: BABYLON.Animation[];
+        animationName: string;
+        animationTargetProperty: string;
         isOpen: boolean;
         selected: BABYLON.Animation;
         currentPathData: string | undefined;
-        anchorPoints: {
-            point: BABYLON.Vector2;
-            anchor: BABYLON.Vector2;
-        }[] | null;
-        keyframes: BABYLON.Vector2[] | null;
+        svgKeyframes: IKeyframeSvgPoint[] | undefined;
+        currentFrame: number;
     }> {
-        private _anchorPoints;
-        private _keyframes;
+        readonly _heightScale: number;
+        private _newAnimations;
+        private _svgKeyframes;
+        private _frames;
+        private _isPlaying;
         constructor(props: IAnimationCurveEditorComponentProps);
+        handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        addAnimation(event: React.MouseEvent<HTMLDivElement>): void;
+        addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
+        updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
         getAnimationProperties(animation: BABYLON.Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
         getPathData(animation: BABYLON.Animation): string;
-        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, heightScale: number, middle: number, easingFunction: BABYLON.EasingFunction): string;
-        linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, heightScale: number, middle: number): string;
-        setAnchorPoint(point: BABYLON.Vector2, anchor: BABYLON.Vector2): void;
-        setKeyframePoint(point: BABYLON.Vector2): void;
+        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
+        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;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
+        changeCurrentFrame(frame: number): void;
         render(): JSX.Element;
     }
 }
@@ -1713,6 +1793,33 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISpriteManagerPropertyGridComponentProps {
+        globalState: GlobalState;
+        spriteManager: BABYLON.SpriteManager;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class SpriteManagerPropertyGridComponent extends React.Component<ISpriteManagerPropertyGridComponentProps> {
+        constructor(props: ISpriteManagerPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISpritePropertyGridComponentProps {
+        globalState: GlobalState;
+        sprite: BABYLON.Sprite;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+    }
+    export class SpritePropertyGridComponent extends React.Component<ISpritePropertyGridComponentProps> {
+        constructor(props: ISpritePropertyGridComponentProps);
+        onManagerLink(): void;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     export class PropertyGridTabComponent extends PaneComponent {
         private _timerIntervalId;
         private _lockObject;
@@ -2066,6 +2173,28 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISpriteManagerTreeItemComponentProps {
+        spriteManager: BABYLON.SpriteManager;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteManagerTreeItemComponent extends React.Component<ISpriteManagerTreeItemComponentProps> {
+        constructor(props: ISpriteManagerTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISpriteTreeItemComponentProps {
+        sprite: BABYLON.Sprite;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteTreeItemComponent extends React.Component<ISpriteTreeItemComponentProps> {
+        constructor(props: ISpriteTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface ITreeItemSpecializedComponentProps {
         label: string;
         entity?: any;
@@ -2121,6 +2250,7 @@ declare module INSPECTOR {
         label: string;
         offset: number;
         filter: BABYLON.Nullable<string>;
+        forceSubitems?: boolean;
         globalState: GlobalState;
         entity?: any;
         selectedEntity: any;

+ 313 - 26
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -561,6 +561,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/floatLineCompone
         step?: string;
         digits?: number;
         useEuler?: boolean;
+        min?: number;
     }
     export class FloatLineComponent extends React.Component<IFloatLineComponentProps, {
         value: string;
@@ -583,8 +584,11 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     import * as React from "react";
     import { Vector2 } from 'babylonjs/Maths/math.vector';
     interface IAnchorSvgPointProps {
-        point: Vector2;
+        control: Vector2;
         anchor: Vector2;
+        active: boolean;
+        type: string;
+        index: string;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -594,50 +598,135 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/keyframeSvgPoint" {
     import * as React from "react";
     import { Vector2 } from 'babylonjs/Maths/math.vector';
+    export interface IKeyframeSvgPoint {
+        keyframePoint: Vector2;
+        rightControlPoint: Vector2 | null;
+        leftControlPoint: Vector2 | null;
+        id: string;
+    }
     interface IKeyframeSvgPointProps {
-        point: Vector2;
+        keyframePoint: Vector2;
+        leftControlPoint: Vector2 | null;
+        rightControlPoint: Vector2 | null;
+        id: string;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/svgDraggableArea" {
+    import * as React from "react";
+    import { Vector2 } from 'babylonjs/Maths/math.vector';
+    import { IKeyframeSvgPoint } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/keyframeSvgPoint";
+    interface ISvgDraggableAreaProps {
+        keyframeSvgPoints: IKeyframeSvgPoint[];
+        updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
+    }
+    export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
+        private _active;
+        private _isCurrentPointControl;
+        private _currentPointIndex;
+        private _draggableArea;
+        constructor(props: ISvgDraggableAreaProps);
+        dragStart(e: React.TouchEvent<SVGSVGElement>): void;
+        dragStart(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<SVGSVGElement>): void;
+        drag(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
+        dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        getMousePosition(e: React.TouchEvent<SVGSVGElement>): Vector2 | undefined;
+        getMousePosition(e: React.MouseEvent<SVGSVGElement, MouseEvent>): Vector2 | undefined;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/timeline" {
+    import * as React from "react";
+    import { IAnimationKey } from 'babylonjs/Animations/animationKey';
+    interface ITimelineProps {
+        keyframes: IAnimationKey[];
+        selected: IAnimationKey;
+        currentFrame: number;
+        onCurrentFrameChange: (frame: number) => void;
+    }
+    export class Timeline extends React.Component<ITimelineProps, {
+        selected: IAnimationKey;
+    }> {
+        readonly _frames: object[];
+        private _scrollable;
+        constructor(props: ITimelineProps);
+        handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        previousKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/playhead" {
+    import * as React from "react";
+    interface IPlayheadProps {
+        frame: number;
+    }
+    export class Playhead extends React.Component<IPlayheadProps> {
+        constructor(props: IPlayheadProps);
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent" {
     import * as React from "react";
     import { Animation } from 'babylonjs/Animations/animation';
     import { Vector2 } from 'babylonjs/Maths/math.vector';
     import { EasingFunction } from 'babylonjs/Animations/easing';
     import { IAnimationKey } from 'babylonjs/Animations/animationKey';
+    import { IKeyframeSvgPoint } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/keyframeSvgPoint";
+    import { Scene } from "babylonjs/scene";
+    import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
     interface IAnimationCurveEditorComponentProps {
         close: (event: any) => void;
+        playOrPause: () => void;
         title: string;
         animations: Animation[];
         entityName: string;
+        scene: Scene;
+        entity: IAnimatable;
     }
     export class AnimationCurveEditorComponent extends React.Component<IAnimationCurveEditorComponentProps, {
+        animations: Animation[];
+        animationName: string;
+        animationTargetProperty: string;
         isOpen: boolean;
         selected: Animation;
         currentPathData: string | undefined;
-        anchorPoints: {
-            point: Vector2;
-            anchor: Vector2;
-        }[] | null;
-        keyframes: Vector2[] | null;
+        svgKeyframes: IKeyframeSvgPoint[] | undefined;
+        currentFrame: number;
     }> {
-        private _anchorPoints;
-        private _keyframes;
+        readonly _heightScale: number;
+        private _newAnimations;
+        private _svgKeyframes;
+        private _frames;
+        private _isPlaying;
         constructor(props: IAnimationCurveEditorComponentProps);
+        handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        addAnimation(event: React.MouseEvent<HTMLDivElement>): void;
+        addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
+        updateKeyframe(keyframe: Vector2, index: number): void;
         getAnimationProperties(animation: Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
         getPathData(animation: Animation): string;
-        curvePath(keyframes: IAnimationKey[], data: string, heightScale: number, middle: number, easingFunction: EasingFunction): string;
-        linearInterpolation(keyframes: IAnimationKey[], data: string, heightScale: number, middle: number): string;
-        setAnchorPoint(point: Vector2, anchor: Vector2): void;
-        setKeyframePoint(point: Vector2): void;
+        drawAllFrames(initialKey: IAnimationKey, endKey: IAnimationKey, easingFunction: EasingFunction): void;
+        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;
         interpolateControlPoints(p0: Vector2, p1: Vector2, u: number, p2: Vector2, v: number, p3: Vector2): Vector2[] | undefined;
+        changeCurrentFrame(frame: number): void;
         render(): JSX.Element;
     }
 }
@@ -2195,6 +2284,45 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/par
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/sprites/spriteManagerPropertyGridComponent" {
+    import * as React from "react";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
+    import { GlobalState } from "babylonjs-inspector/components/globalState";
+    import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+    interface ISpriteManagerPropertyGridComponentProps {
+        globalState: GlobalState;
+        spriteManager: SpriteManager;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: Observable<any>;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    }
+    export class SpriteManagerPropertyGridComponent extends React.Component<ISpriteManagerPropertyGridComponentProps> {
+        constructor(props: ISpriteManagerPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/sprites/spritePropertyGridComponent" {
+    import * as React from "react";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
+    import { GlobalState } from "babylonjs-inspector/components/globalState";
+    import { Sprite } from 'babylonjs/Sprites/sprite';
+    interface ISpritePropertyGridComponentProps {
+        globalState: GlobalState;
+        sprite: Sprite;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+        onSelectionChangedObservable?: Observable<any>;
+    }
+    export class SpritePropertyGridComponent extends React.Component<ISpritePropertyGridComponentProps> {
+        constructor(props: ISpritePropertyGridComponentProps);
+        onManagerLink(): void;
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGridTabComponent" {
     import { PaneComponent, IPaneComponentProps } from "babylonjs-inspector/components/actionTabs/paneComponent";
     export class PropertyGridTabComponent extends PaneComponent {
@@ -2611,6 +2739,34 @@ declare module "babylonjs-inspector/components/sceneExplorer/entities/particleSy
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/sceneExplorer/entities/spriteManagerTreeItemComponent" {
+    import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+    import * as React from 'react';
+    import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+    interface ISpriteManagerTreeItemComponentProps {
+        spriteManager: SpriteManager;
+        extensibilityGroups?: IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteManagerTreeItemComponent extends React.Component<ISpriteManagerTreeItemComponentProps> {
+        constructor(props: ISpriteManagerTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-inspector/components/sceneExplorer/entities/spriteTreeItemComponent" {
+    import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+    import * as React from 'react';
+    import { Sprite } from 'babylonjs/Sprites/sprite';
+    interface ISpriteTreeItemComponentProps {
+        sprite: Sprite;
+        extensibilityGroups?: IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteTreeItemComponent extends React.Component<ISpriteTreeItemComponentProps> {
+        constructor(props: ISpriteTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/sceneExplorer/treeItemSpecializedComponent" {
     import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
     import * as React from "react";
@@ -2678,6 +2834,7 @@ declare module "babylonjs-inspector/components/sceneExplorer/treeItemComponent"
         label: string;
         offset: number;
         filter: Nullable<string>;
+        forceSubitems?: boolean;
         globalState: GlobalState;
         entity?: any;
         selectedEntity: any;
@@ -3361,6 +3518,7 @@ declare module INSPECTOR {
         step?: string;
         digits?: number;
         useEuler?: boolean;
+        min?: number;
     }
     export class FloatLineComponent extends React.Component<IFloatLineComponentProps, {
         value: string;
@@ -3381,8 +3539,11 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IAnchorSvgPointProps {
-        point: BABYLON.Vector2;
+        control: BABYLON.Vector2;
         anchor: BABYLON.Vector2;
+        active: boolean;
+        type: string;
+        index: string;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -3390,8 +3551,17 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export interface IKeyframeSvgPoint {
+        keyframePoint: BABYLON.Vector2;
+        rightControlPoint: BABYLON.Vector2 | null;
+        leftControlPoint: BABYLON.Vector2 | null;
+        id: string;
+    }
     interface IKeyframeSvgPointProps {
-        point: BABYLON.Vector2;
+        keyframePoint: BABYLON.Vector2;
+        leftControlPoint: BABYLON.Vector2 | null;
+        rightControlPoint: BABYLON.Vector2 | null;
+        id: string;
     }
     export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps> {
         constructor(props: IKeyframeSvgPointProps);
@@ -3399,36 +3569,103 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISvgDraggableAreaProps {
+        keyframeSvgPoints: IKeyframeSvgPoint[];
+        updatePosition: (updatedKeyframe: IKeyframeSvgPoint, index: number) => void;
+    }
+    export class SvgDraggableArea extends React.Component<ISvgDraggableAreaProps> {
+        private _active;
+        private _isCurrentPointControl;
+        private _currentPointIndex;
+        private _draggableArea;
+        constructor(props: ISvgDraggableAreaProps);
+        dragStart(e: React.TouchEvent<SVGSVGElement>): void;
+        dragStart(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<SVGSVGElement>): void;
+        drag(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
+        dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        getMousePosition(e: React.TouchEvent<SVGSVGElement>): BABYLON.Vector2 | undefined;
+        getMousePosition(e: React.MouseEvent<SVGSVGElement, MouseEvent>): BABYLON.Vector2 | undefined;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ITimelineProps {
+        keyframes: BABYLON.IAnimationKey[];
+        selected: BABYLON.IAnimationKey;
+        currentFrame: number;
+        onCurrentFrameChange: (frame: number) => void;
+    }
+    export class Timeline extends React.Component<ITimelineProps, {
+        selected: BABYLON.IAnimationKey;
+    }> {
+        readonly _frames: object[];
+        private _scrollable;
+        constructor(props: ITimelineProps);
+        handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        previousKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IPlayheadProps {
+        frame: number;
+    }
+    export class Playhead extends React.Component<IPlayheadProps> {
+        constructor(props: IPlayheadProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface IAnimationCurveEditorComponentProps {
         close: (event: any) => void;
+        playOrPause: () => void;
         title: string;
         animations: BABYLON.Animation[];
         entityName: string;
+        scene: BABYLON.Scene;
+        entity: BABYLON.IAnimatable;
     }
     export class AnimationCurveEditorComponent extends React.Component<IAnimationCurveEditorComponentProps, {
+        animations: BABYLON.Animation[];
+        animationName: string;
+        animationTargetProperty: string;
         isOpen: boolean;
         selected: BABYLON.Animation;
         currentPathData: string | undefined;
-        anchorPoints: {
-            point: BABYLON.Vector2;
-            anchor: BABYLON.Vector2;
-        }[] | null;
-        keyframes: BABYLON.Vector2[] | null;
+        svgKeyframes: IKeyframeSvgPoint[] | undefined;
+        currentFrame: number;
     }> {
-        private _anchorPoints;
-        private _keyframes;
+        readonly _heightScale: number;
+        private _newAnimations;
+        private _svgKeyframes;
+        private _frames;
+        private _isPlaying;
         constructor(props: IAnimationCurveEditorComponentProps);
+        handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        addAnimation(event: React.MouseEvent<HTMLDivElement>): void;
+        addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
+        updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
         getAnimationProperties(animation: BABYLON.Animation): {
             easingType: string | undefined;
             easingMode: number | undefined;
         };
         getPathData(animation: BABYLON.Animation): string;
-        curvePath(keyframes: BABYLON.IAnimationKey[], data: string, heightScale: number, middle: number, easingFunction: BABYLON.EasingFunction): string;
-        linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, heightScale: number, middle: number): string;
-        setAnchorPoint(point: BABYLON.Vector2, anchor: BABYLON.Vector2): void;
-        setKeyframePoint(point: BABYLON.Vector2): void;
+        drawAllFrames(initialKey: BABYLON.IAnimationKey, endKey: BABYLON.IAnimationKey, easingFunction: BABYLON.EasingFunction): void;
+        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;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
+        changeCurrentFrame(frame: number): void;
         render(): JSX.Element;
     }
 }
@@ -4582,6 +4819,33 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISpriteManagerPropertyGridComponentProps {
+        globalState: GlobalState;
+        spriteManager: BABYLON.SpriteManager;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class SpriteManagerPropertyGridComponent extends React.Component<ISpriteManagerPropertyGridComponentProps> {
+        constructor(props: ISpriteManagerPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISpritePropertyGridComponentProps {
+        globalState: GlobalState;
+        sprite: BABYLON.Sprite;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+    }
+    export class SpritePropertyGridComponent extends React.Component<ISpritePropertyGridComponentProps> {
+        constructor(props: ISpritePropertyGridComponentProps);
+        onManagerLink(): void;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     export class PropertyGridTabComponent extends PaneComponent {
         private _timerIntervalId;
         private _lockObject;
@@ -4935,6 +5199,28 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ISpriteManagerTreeItemComponentProps {
+        spriteManager: BABYLON.SpriteManager;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteManagerTreeItemComponent extends React.Component<ISpriteManagerTreeItemComponentProps> {
+        constructor(props: ISpriteManagerTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISpriteTreeItemComponentProps {
+        sprite: BABYLON.Sprite;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class SpriteTreeItemComponent extends React.Component<ISpriteTreeItemComponentProps> {
+        constructor(props: ISpriteTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface ITreeItemSpecializedComponentProps {
         label: string;
         entity?: any;
@@ -4990,6 +5276,7 @@ declare module INSPECTOR {
         label: string;
         offset: number;
         filter: BABYLON.Nullable<string>;
+        forceSubitems?: boolean;
         globalState: GlobalState;
         entity?: any;
         selectedEntity: any;

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":115811,"engineOnly":152214,"sceneOnly":511356,"minGridMaterial":644589,"minStandardMaterial":786440}
+{"thinEngineOnly":115808,"engineOnly":152211,"sceneOnly":511353,"minGridMaterial":644586,"minStandardMaterial":786437}

+ 142 - 8
dist/preview release/viewer/babylon.module.d.ts

@@ -10224,6 +10224,10 @@ declare module "babylonjs/Sprites/spriteManager" {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -10233,6 +10237,10 @@ declare module "babylonjs/Sprites/spriteManager" {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -10242,6 +10250,14 @@ declare module "babylonjs/Sprites/spriteManager" {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -10312,6 +10328,23 @@ declare module "babylonjs/Sprites/spriteManager" {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -10344,6 +10377,11 @@ declare module "babylonjs/Sprites/spriteManager" {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -18636,11 +18674,13 @@ declare module "babylonjs/Sprites/sprite" {
     import { ISpriteManager } from "babylonjs/Sprites/spriteManager";
     import { Color4 } from "babylonjs/Maths/math.color";
     import { Observable } from "babylonjs/Misc/observable";
+    import { IAnimatable } from "babylonjs/Animations/animatable.interface";
+    import { Animation } from "babylonjs/Animations/animation";
     /**
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -18658,13 +18698,13 @@ declare module "babylonjs/Sprites/sprite" {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -18704,6 +18744,14 @@ declare module "babylonjs/Sprites/sprite" {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -18712,6 +18760,23 @@ declare module "babylonjs/Sprites/sprite" {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -27749,6 +27814,9 @@ declare module "babylonjs/Materials/standardMaterial" {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;
@@ -86006,6 +86074,10 @@ declare module BABYLON {
      */
     export interface ISpriteManager extends IDisposable {
         /**
+         * Gets manager's name
+         */
+        name: string;
+        /**
          * Restricts the camera to viewing objects with the same layerMask.
          * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
          */
@@ -86015,6 +86087,10 @@ declare module BABYLON {
          */
         isPickable: boolean;
         /**
+         * Gets the hosting scene
+         */
+        scene: Scene;
+        /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
@@ -86024,6 +86100,14 @@ declare module BABYLON {
          */
         sprites: Array<Sprite>;
         /**
+         * Gets or sets the spritesheet texture
+         */
+        texture: Texture;
+        /** Defines the default width of a cell in the spritesheet */
+        cellWidth: number;
+        /** Defines the default height of a cell in the spritesheet */
+        cellHeight: number;
+        /**
          * Tests the intersection of a sprite with a specific ray.
          * @param ray The ray we are sending to test the collision
          * @param camera The camera space we are sending rays in
@@ -86094,6 +86178,23 @@ declare module BABYLON {
         private _effectBase;
         private _effectFog;
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the array of sprites
+         */
+        get children(): Sprite[];
+        /**
+         * Gets the hosting scene
+         */
+        get scene(): Scene;
+        /**
+         * Gets or sets the capacity of the manager
+         */
+        get capacity(): number;
+        set capacity(value: number);
+        /**
          * Gets or sets the spritesheet texture
          */
         get texture(): Texture;
@@ -86126,6 +86227,11 @@ declare module BABYLON {
         constructor(
         /** defines the manager's name */
         name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number, fromPacked?: boolean, spriteJSON?: any | null);
+        /**
+         * Returns the string "SpriteManager"
+         * @returns "SpriteManager"
+         */
+        getClassName(): string;
         private _makePacked;
         private _appendSpriteVertex;
         private _checkTextureAlpha;
@@ -94117,7 +94223,7 @@ declare module BABYLON {
      * Class used to represent a sprite
      * @see http://doc.babylonjs.com/babylon101/sprites
      */
-    export class Sprite {
+    export class Sprite implements IAnimatable {
         /** defines the name */
         name: string;
         /** Gets or sets the current world position */
@@ -94135,13 +94241,13 @@ declare module BABYLON {
         /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
         cellRef: string;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-        invertU: number;
+        invertU: boolean;
         /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-        invertV: number;
+        invertV: boolean;
         /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
         disposeWhenFinishedAnimating: boolean;
         /** Gets the list of attached animations */
-        animations: Animation[];
+        animations: Nullable<Array<Animation>>;
         /** Gets or sets a boolean indicating if the sprite can be picked */
         isPickable: boolean;
         /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -94181,6 +94287,14 @@ declare module BABYLON {
         get size(): number;
         set size(value: number);
         /**
+         * Gets or sets the unique id of the sprite
+         */
+        uniqueId: number;
+        /**
+         * Gets the manager of this sprite
+         */
+        get manager(): ISpriteManager;
+        /**
          * Creates a new Sprite
          * @param name defines the name
          * @param manager defines the manager
@@ -94189,6 +94303,23 @@ declare module BABYLON {
         /** defines the name */
         name: string, manager: ISpriteManager);
         /**
+         * Returns the string "Sprite"
+         * @returns "Sprite"
+         */
+        getClassName(): string;
+        /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+        get fromIndex(): number;
+        set fromIndex(value: number);
+        /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+        get toIndex(): number;
+        set toIndex(value: number);
+        /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+        get loopAnimation(): boolean;
+        set loopAnimation(value: boolean);
+        /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+        get delay(): number;
+        set delay(value: number);
+        /**
          * Starts an animation
          * @param from defines the initial key
          * @param to defines the end key
@@ -102872,6 +103003,9 @@ declare module BABYLON {
         PREMULTIPLYALPHA: boolean;
         ALPHATEST_AFTERALLALPHACOMPUTATIONS: boolean;
         ALPHABLEND: boolean;
+        RGBDLIGHTMAP: boolean;
+        RGBDREFLECTION: boolean;
+        RGBDREFRACTION: boolean;
         IMAGEPROCESSING: boolean;
         VIGNETTE: boolean;
         VIGNETTEBLENDMODEMULTIPLY: boolean;

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


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


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

@@ -6,6 +6,7 @@
 - Added the `ShadowDepthWrapper` class to support accurate shadow generation for custom as well as node material shaders. [Doc](https://doc.babylonjs.com/babylon101/shadows#custom-shadow-map-shaders) ([Popov72](https://github.com/Popov72))
 - Added Babylon.js Texture [tools](https://www.babylonjs.com/tools/ibl) to prefilter HDR files ([Sebavan](https://github.com/sebavan/))
 - Added editing of PBR materials and Post processes in the node material editor ([Popov72](https://github.com/Popov72))
+- Added Curve editor to view selected entity's animations in the Inspector ([pixelspace](https://github.com/devpixelspace))
 
 ## Updates
 
@@ -42,9 +43,7 @@
 - Added right click options to create PBR and Standard Materials ([Deltakosh](https://github.com/deltakosh))
 - Added support for recording GIF ([Deltakosh](https://github.com/deltakosh))
 - Popup Window available (To be used in Curve Editor) ([pixelspace](https://github.com/devpixelspace))
-- Curve Editor to view current entity's animations (Read only) ([pixelspace](https://github.com/devpixelspace))
 - Add support to update inspector when switching to new scene ([belfortk](https://github.com/belfortk))
-- Drag keyframes in Curve Editor ([pixelspace](https://github.com/devpixelspace))
 
 ### Cameras
 
@@ -84,6 +83,7 @@
 - Added `AddAttribute` to `CustomMaterial` and `PBRCustomMaterial` ([Popov72](https://github.com/Popov72))
 - `setTexture` and `setTextureArray` from `ShaderMaterial` take now a `BaseTexture` as input instead of a `Texture`, allowing to pass a `CubeTexture` ([Popov72](https://github.com/Popov72))
 - Allow parenthesis usage in `#if` expressions in shader code ([Popov72](https://github.com/Popov72))
+- Added to `StandardMaterial` RGBD ReflectionTexture, RefractionTexture and LightmapTexture support. ([MackeyK24](https://github.com/MackeyK24))
 
 ### WebXR
 

+ 9 - 1
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -18,7 +18,8 @@ interface IFloatLineComponentProps {
     additionalClass?: string;
     step?: string,
     digits?: number;
-    useEuler?: boolean
+    useEuler?: boolean;
+    min?: number
 }
 
 export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
@@ -83,6 +84,13 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
             valueAsNumber = parseFloat(valueString);
         }
 
+        if (!isNaN(valueAsNumber) && this.props.min !== undefined) {
+            if (valueAsNumber < this.props.min) {
+                valueAsNumber = this.props.min;
+                valueString = valueAsNumber.toString();
+            }            
+        }
+
         this._localChange = true;
         this.setState({ value: valueString });
 

+ 1 - 1
inspector/src/components/actionTabs/lines/sliderLineComponent.tsx

@@ -49,7 +49,7 @@ export class SliderLineComponent extends React.Component<ISliderLineComponentPro
             currentState = nextProps.maximum;
         }
 
-        if (currentState !== nextState.value || this._localChange) {
+        if (currentState !== nextState.value || this._localChange || nextProps.maximum !== this.props.maximum || nextProps.minimum !== this.props.minimum) {
             nextState.value = currentState;
             this._localChange = false;
             return true;

+ 22 - 0
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -91,6 +91,10 @@ import { MultiMaterial } from 'babylonjs/Materials/multiMaterial';
 import { MultiMaterialPropertyGridComponent } from './propertyGrids/materials/multiMaterialPropertyGridComponent';
 import { ParticleSystemPropertyGridComponent } from './propertyGrids/particleSystems/particleSystemPropertyGridComponent';
 import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+import { SpriteManagerPropertyGridComponent } from './propertyGrids/sprites/spriteManagerPropertyGridComponent';
+import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+import { SpritePropertyGridComponent } from './propertyGrids/sprites/spritePropertyGridComponent';
+import { Sprite } from 'babylonjs/Sprites/sprite';
 
 export class PropertyGridTabComponent extends PaneComponent {
     private _timerIntervalId: number;
@@ -137,6 +141,24 @@ export class PropertyGridTabComponent extends PaneComponent {
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
 
+            if (className === "Sprite") {
+                const sprite = entity as Sprite;
+                return (<SpritePropertyGridComponent sprite={sprite}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "SpriteManager") {
+                const spriteManager = entity as SpriteManager;
+                return (<SpriteManagerPropertyGridComponent spriteManager={spriteManager}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}                    
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
             if (className.indexOf("Mesh") !== -1) {
                 const mesh = entity as Mesh;
                 if (mesh.getTotalVertices() > 0) {

+ 109 - 93
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx

@@ -7,6 +7,8 @@ import { EasingFunction, BezierCurveEase } from 'babylonjs/Animations/easing';
 import { IAnimationKey } from 'babylonjs/Animations/animationKey';
 import { IKeyframeSvgPoint } from './keyframeSvgPoint';
 import { SvgDraggableArea } from './svgDraggableArea';
+import { Timeline } from './timeline';
+import { Playhead } from './playhead';
 import { Scene } from "babylonjs/scene";
 import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
 
@@ -22,7 +24,7 @@ interface IAnimationCurveEditorComponentProps {
     entity: IAnimatable;
 }
 
-export class AnimationCurveEditorComponent extends React.Component<IAnimationCurveEditorComponentProps, { animations: Animation[], animationName: string, animationTargetProperty: string, isOpen: boolean, selected: Animation, currentPathData: string | undefined, svgKeyframes: IKeyframeSvgPoint[] | undefined }> {
+export class AnimationCurveEditorComponent extends React.Component<IAnimationCurveEditorComponentProps, { animations: Animation[], animationName: string, animationTargetProperty: string, isOpen: boolean, selected: Animation, currentPathData: string | undefined, svgKeyframes: IKeyframeSvgPoint[] | undefined, currentFrame: number }> {
 
     readonly _heightScale: number = 100;
     private _newAnimations: Animation[] = [];
@@ -31,7 +33,7 @@ export class AnimationCurveEditorComponent extends React.Component<IAnimationCur
     private _isPlaying: boolean = false;
     constructor(props: IAnimationCurveEditorComponentProps) {
         super(props);
-        this.state = { animations: this._newAnimations, selected: this.props.animations[0], isOpen: true, currentPathData: this.getPathData(this.props.animations[0]), svgKeyframes: this._svgKeyframes, animationTargetProperty: 'position.x', animationName: "" }
+        this.state = { animations: this._newAnimations, selected: this.props.animations[0], isOpen: true, currentPathData: this.getPathData(this.props.animations[0]), svgKeyframes: this._svgKeyframes, animationTargetProperty: 'position.x', animationName: "", currentFrame: 0 }
 
     }
 
@@ -340,12 +342,12 @@ export class AnimationCurveEditorComponent extends React.Component<IAnimationCur
     }
 
     isAnimationPlaying() {
-          this._isPlaying = this.props.scene.getAllAnimatablesByTarget(this.props.entity).length > 0;
-           if (this._isPlaying){
+        this._isPlaying = this.props.scene.getAllAnimatablesByTarget(this.props.entity).length > 0;
+        if (this._isPlaying) {
             this.props.playOrPause();
-           } else {
-               this._isPlaying = false;
-           }
+        } else {
+            this._isPlaying = false;
+        }
     }
 
     selectAnimation(animation: Animation) {
@@ -404,6 +406,10 @@ export class AnimationCurveEditorComponent extends React.Component<IAnimationCur
 
     }
 
+    changeCurrentFrame(frame: number){
+        this.setState({ currentFrame: frame });
+    }
+
     render() {
         return (
             <div id="animation-curve-editor">
@@ -415,104 +421,114 @@ export class AnimationCurveEditorComponent extends React.Component<IAnimationCur
                 </div>
                 <div className="content">
 
-                    <div className="animation-list">
+                    <div className="row">
+                        <div className="animation-list">
 
-                        <div>
                             <div>
-                                <label>Animation Name</label>
-                                <input type="text" value={this.state.animationName} onChange={(e) => this.handleNameChange(e)}></input>
-                            </div>
-                            <div>
-                                <label>Target Property</label>
-                                <input type="text" value={this.state.animationTargetProperty} onChange={(e) => this.handlePropertyChange(e)}></input>
-                            </div>
-                            <div className="add" onClick={(e) => this.addAnimation(e)}>
-                                <FontAwesomeIcon icon={faPlusCircle} />
+                                <div>
+                                    <label>Animation Name</label>
+                                    <input type="text" value={this.state.animationName} onChange={(e) => this.handleNameChange(e)}></input>
+                                </div>
+                                <div>
+                                    <label>Target Property</label>
+                                    <input type="text" value={this.state.animationTargetProperty} onChange={(e) => this.handlePropertyChange(e)}></input>
+                                </div>
+                                <div className="add" onClick={(e) => this.addAnimation(e)}>
+                                    <FontAwesomeIcon icon={faPlusCircle} />
+                                </div>
                             </div>
-                        </div>
 
-                        <h2>{this.props.entityName}</h2>
-                        <ul>
-                            {this.props.animations && this.props.animations.map((animation, i) => {
-                                return <li className={this.state.selected.name === animation.name ? 'active' : ''} key={i} onClick={() => this.selectAnimation(animation)}>{animation.name} <strong>{animation.targetProperty}</strong></li>
-                            })}
+                            <h2>{this.props.entityName}</h2>
+                            <ul>
+                                {this.props.animations && this.props.animations.map((animation, i) => {
+                                    return <li className={this.state.selected.name === animation.name ? 'active' : ''} key={i} onClick={() => this.selectAnimation(animation)}>{animation.name} <strong>{animation.targetProperty}</strong></li>
+                                })}
 
-                        </ul>
+                            </ul>
 
-                        <h2>New Animations</h2>
-                        <ul>
-                            {this.state.animations && this.state.animations.map((animation, i) => {
-                                return <li className={this.state.selected.name === animation.name ? 'active' : ''} key={i} onClick={() => this.selectAnimation(animation)}>{animation.name} <strong>{animation.targetProperty}</strong></li>
-                            })}
+                            <h2>New Animations</h2>
+                            <ul>
+                                {this.state.animations && this.state.animations.map((animation, i) => {
+                                    return <li className={this.state.selected.name === animation.name ? 'active' : ''} key={i} onClick={() => this.selectAnimation(animation)}>{animation.name} <strong>{animation.targetProperty}</strong></li>
+                                })}
 
-                        </ul>
-                    </div>
-                    <div className="graph-chart">
-
-                        {this.state.svgKeyframes && <SvgDraggableArea keyframeSvgPoints={this.state.svgKeyframes} updatePosition={(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number) => this.renderPoints(updatedSvgKeyFrame, index)}>
-
-                            {/* Frame Labels  */}
-                            <text x="10" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>10</text>
-                            <text x="20" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>20</text>
-                            <text x="30" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>30</text>
-                            <text x="40" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>40</text>
-                            <text x="50" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>50</text>
-                            <text x="60" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>60</text>
-                            <text x="70" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>70</text>
-                            <text x="80" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>80</text>
-                            <text x="90" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>90</text>
-
-                            { /* Vertical Grid  */}
-                            <line x1="10" y1="0" x2="10" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="20" y1="0" x2="20" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="30" y1="0" x2="30" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="40" y1="0" x2="40" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="50" y1="0" x2="50" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="60" y1="0" x2="60" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="70" y1="0" x2="70" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="80" y1="0" x2="80" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="90" y1="0" x2="90" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-
-                            { /* Value Labels  */}
-                            <text x="0" y="10" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.8</text>
-                            <text x="0" y="20" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.6</text>
-                            <text x="0" y="30" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.4</text>
-                            <text x="0" y="40" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.2</text>
-                            <text x="0" y="50" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1</text>
-                            <text x="0" y="60" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.8</text>
-                            <text x="0" y="70" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.6</text>
-                            <text x="0" y="80" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.4</text>
-                            <text x="0" y="90" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.2</text>
-
-                            { /* Horizontal Grid  */}
-                            <line x1="0" y1="10" x2="100" y2="10" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="20" x2="100" y2="20" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="30" x2="100" y2="30" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="40" x2="100" y2="40" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="50" x2="100" y2="50" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="60" x2="100" y2="60" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="70" x2="100" y2="70" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="80" x2="100" y2="80" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-                            <line x1="0" y1="90" x2="100" y2="90" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
-
-                            { /* Single Curve -Modify this for multiple selection and view  */}
-                            <path id="curve" d={this.state.currentPathData} style={{ stroke: 'red', fill: 'none', strokeWidth: '0.5' }}></path>
-
-                            {this._frames && this._frames.map(frame =>
-                                <svg x={frame.x} y={frame.y} style={{ overflow: 'visible' }}>
-                                    <circle cx="0" cy="0" r="2" stroke="black" strokeWidth="1" fill="white" />
-                                </svg>
-
-                            )}
-
-                        </SvgDraggableArea>
-
-                        }
+                            </ul>
+                        </div>
+                        <div className="graph-chart">
+
+                            <Playhead frame={this.state.currentFrame}/>
+
+                            {this.state.svgKeyframes && <SvgDraggableArea keyframeSvgPoints={this.state.svgKeyframes} updatePosition={(updatedSvgKeyFrame: IKeyframeSvgPoint, index: number) => this.renderPoints(updatedSvgKeyFrame, index)}>
+
+                                {/* Frame Labels  */}
+                                <text x="10" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>10</text>
+                                <text x="20" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>20</text>
+                                <text x="30" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>30</text>
+                                <text x="40" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>40</text>
+                                <text x="50" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>50</text>
+                                <text x="60" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>60</text>
+                                <text x="70" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>70</text>
+                                <text x="80" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>80</text>
+                                <text x="90" y="0" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>90</text>
+
+                                { /* Vertical Grid  */}
+                                <line x1="10" y1="0" x2="10" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="20" y1="0" x2="20" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="30" y1="0" x2="30" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="40" y1="0" x2="40" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="50" y1="0" x2="50" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="60" y1="0" x2="60" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="70" y1="0" x2="70" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="80" y1="0" x2="80" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="90" y1="0" x2="90" y2="100" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+
+                                { /* Value Labels  */}
+                                <text x="0" y="10" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.8</text>
+                                <text x="0" y="20" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.6</text>
+                                <text x="0" y="30" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.4</text>
+                                <text x="0" y="40" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1.2</text>
+                                <text x="0" y="50" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>1</text>
+                                <text x="0" y="60" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.8</text>
+                                <text x="0" y="70" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.6</text>
+                                <text x="0" y="80" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.4</text>
+                                <text x="0" y="90" dx="-1em" style={{ font: 'italic 0.2em sans-serif' }}>0.2</text>
+
+                                { /* Horizontal Grid  */}
+                                <line x1="0" y1="10" x2="100" y2="10" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="20" x2="100" y2="20" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="30" x2="100" y2="30" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="40" x2="100" y2="40" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="50" x2="100" y2="50" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="60" x2="100" y2="60" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="70" x2="100" y2="70" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="80" x2="100" y2="80" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+                                <line x1="0" y1="90" x2="100" y2="90" style={{ stroke: 'black', strokeWidth: '0.2px' }}></line>
+
+                                { /* Single Curve -Modify this for multiple selection and view  */}
+                                <path id="curve" d={this.state.currentPathData} style={{ stroke: 'red', fill: 'none', strokeWidth: '0.5' }}></path>
+
+                                {this._frames && this._frames.map(frame =>
+                                    <svg x={frame.x} y={frame.y} style={{ overflow: 'visible' }}>
+                                        <circle cx="0" cy="0" r="2" stroke="black" strokeWidth="1" fill="white" />
+                                    </svg>
+
+                                )}
+
+                            </SvgDraggableArea>
+
+                            }
 
                         Animation name: {this.state.selected.name}
 
+                        </div>
+                       
+                    </div>
+                    <div className="row">
+                            <Timeline currentFrame={this.state.currentFrame} onCurrentFrameChange={(frame: number) => this.changeCurrentFrame(frame)} keyframes={this.state.selected.getKeys()} selected={this.state.selected.getKeys()[0]}></Timeline>
                     </div>
                 </div>
+
+
             </div>
         );
     }

+ 94 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -26,11 +26,70 @@
         display: flex;
         align-items: flex-start;
         justify-content: flex-start;
+        flex-direction: column;
+
+        .row {
+            display: flex;
+            align-items: stretch;
+            justify-content: flex-start;
+            flex-direction: row;
+            width: 100vw;
+
+            .timeline{
+                width: 100vw;
+                background: gray;
+                display: flex;
+                align-items: center;
+                justify-content: stretch;
+                height: 2.5rem;
+
+                .display-line {
+                    width: 80vw;
+                    height: 2em;
+                    overflow: hidden;
+                    overflow-x: scroll;
+                    scrollbar-color: cornflowerblue slategrey;
+                    scrollbar-width: thin;
+                    margin-right: 1.3em;
+                    padding-left: 1em;
+                    padding-right: 1em;
+
+                    &::-webkit-scrollbar{
+                        height: 0.4em;
+                    }
+
+                    &::-webkit-scrollbar-track {
+                        box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+                      }
+                       
+                    &::-webkit-scrollbar-thumb {
+                        background-color: cornflowerblue;
+                        outline: 1px solid slategrey;
+                      }
+                }
+
+                .controls {
+                    display: flex;
+                    justify-content: center;
+                    align-items: center;
+                    width: 8em;
+
+                    .input-frame input {
+                        width: 3em;
+                    }
+
+                    .button {
+                        margin-left: 0.5em;
+                        margin-right: 0.5em;
+                    }
+                }
+            }
+        }
 
         .animation-list{
             padding: 1.5rem;
             background: lightgrey;
-            height: 100vh;
+            // height: 100vh;
             ul {
                 list-style:none;
                 padding-left: 0px;
@@ -77,6 +136,40 @@
                 overflow: visible;
                 background-color: 'aliceblue';
             }
+
+            .playhead-wrapper {
+                position: relative;
+                left: -13px;
+            }
+
+            .playhead {
+                width: fit-content;
+                background-color: #ffc60e;
+                color: black;
+                text-align: center;
+                min-width: 2em;
+                justify-content: center;
+                display: flex;
+                padding: 0.1em;
+                font-size: 0.75em;
+            }
+
+            .playhead-triangle {
+                background-color: transparent;
+                width: 0px;
+                height: 0px;
+                border-left: 13.5px solid transparent;
+                border-right: 13.5px solid transparent;
+                border-top: 12px solid #ffc60e;
+            }
+
+            .playhead-line {
+                width: 2px;
+                height: calc(45vh - 100px);
+                background-color: rgb(255, 198, 14);
+                position: absolute;
+                margin-left: 12.5px;
+            }
         }
     }
 

+ 24 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/animations/playhead.tsx

@@ -0,0 +1,24 @@
+
+import * as React from "react";
+
+interface IPlayheadProps {
+   frame: number;
+}
+
+export class Playhead extends React.Component<IPlayheadProps>{ 
+    constructor(props: IPlayheadProps) {
+        super(props);
+    }
+    
+    render() { 
+       return (
+           <div className="playhead-wrapper" id="playhead" style={{left: `calc(${this.props.frame * 3.02}px - 13px)`}}>
+            <div className="playhead">{this.props.frame}</div>
+            <div className="playhead-triangle"></div>
+            <div className="playhead-line"></div>
+           </div>
+        )
+    }
+} 
+
+

+ 116 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/animations/timeline.tsx

@@ -0,0 +1,116 @@
+
+import * as React from "react";
+import { IAnimationKey } from 'babylonjs/Animations/animationKey';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faCaretRight, faCaretLeft, faStepBackward, faStepForward } from "@fortawesome/free-solid-svg-icons";
+
+interface ITimelineProps {
+    keyframes: IAnimationKey[];
+    selected: IAnimationKey;
+    currentFrame: number;
+    onCurrentFrameChange: (frame: number) => void;
+}
+
+
+export class Timeline extends React.Component<ITimelineProps, { selected: IAnimationKey }>{
+    readonly _frames: object[] = Array(300).fill({});
+    private _scrollable: React.RefObject<HTMLDivElement>;
+    constructor(props: ITimelineProps) {
+        super(props);
+        this.state = { selected: this.props.selected };
+        this._scrollable = React.createRef();
+    }
+
+    handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
+        this.props.onCurrentFrameChange(parseInt(event.target.value));
+        event.preventDefault();
+    }
+
+    nextFrame(event: React.MouseEvent<HTMLDivElement>) {
+        event.preventDefault();
+        this.props.onCurrentFrameChange(this.props.currentFrame + 1);
+        (this._scrollable.current as HTMLDivElement).scrollLeft = this.props.currentFrame * 5;
+    }
+
+    previousFrame(event: React.MouseEvent<HTMLDivElement>) {
+        event.preventDefault();
+        if (this.props.currentFrame !== 0) {
+            this.props.onCurrentFrameChange(this.props.currentFrame - 1);
+            (this._scrollable.current as HTMLDivElement).scrollLeft = -(this.props.currentFrame * 5);
+        }
+    }
+
+    nextKeyframe(event: React.MouseEvent<HTMLDivElement>) {
+        event.preventDefault();
+        let first = this.props.keyframes.find(kf => kf.frame > this.props.currentFrame);
+        if (first) {
+            this.props.onCurrentFrameChange(first.frame);
+            this.setState({ selected: first });
+            (this._scrollable.current as HTMLDivElement).scrollLeft = first.frame * 5;
+        }
+    }
+
+    previousKeyframe(event: React.MouseEvent<HTMLDivElement>) {
+        event.preventDefault();
+        let first = this.props.keyframes.find(kf => kf.frame < this.props.currentFrame);
+        if (first) {
+            this.props.onCurrentFrameChange(first.frame);
+            this.setState({ selected: first });
+            (this._scrollable.current as HTMLDivElement).scrollLeft = -(first.frame * 5);
+        }
+    }
+
+    render() {
+        return (
+            <>
+                <div className="timeline">
+                    <div ref={this._scrollable} className="display-line">
+                        <svg viewBox="0 0 2010 100" style={{ width: 2000 }}>
+
+                            <line x1={this.props.currentFrame * 10} y1="10" x2={this.props.currentFrame * 10} y2="20" style={{ stroke: '#12506b', strokeWidth: 6 }} />
+
+                            {
+                                this.props.keyframes.map((kf, i) => {
+
+                                    return <svg key={`kf_${i}`}>
+                                        <line x1={kf.frame * 10} y1="10" x2={kf.frame * 10} y2="20" style={{ stroke: 'red', strokeWidth: 6 }} />
+                                    </svg>
+
+                                })
+                            }
+
+                            {
+                                this._frames.map((frame, i) => {
+
+                                    return <svg key={`tl_${i}`}>
+                                        {i % 10 === 0 ? <text x={(i * 10) - 3} y="8" style={{ fontSize: 10 }}>{i}</text> : null}
+                                        <line x1={i * 10} y1="10" x2={i * 10} y2="20" style={{ stroke: 'black', strokeWidth: 0.5 }} />
+                                    </svg>
+
+                                })
+                            }
+
+                        </svg>
+                    </div>
+                    <div className="controls">
+                        <div className="input-frame">
+                            <input type="number" value={this.props.currentFrame} onChange={(e) => this.handleInputChange(e)}></input>
+                        </div>
+                        <div className="previous-frame button" onClick={(e) => this.previousFrame(e)}>
+                            <FontAwesomeIcon icon={faCaretLeft} />
+                        </div>
+                        <div className="previous-key-frame button" onClick={(e) => this.previousKeyframe(e)}>
+                            <FontAwesomeIcon icon={faStepBackward} />
+                        </div>
+                        <div className="next-key-frame button" onClick={(e) => this.nextKeyframe(e)}>
+                            <FontAwesomeIcon icon={faStepForward} />
+                        </div>
+                        <div className="next-frame button" onClick={(e) => this.nextFrame(e)}>
+                            <FontAwesomeIcon icon={faCaretRight} />
+                        </div>
+                    </div>
+                </div>
+            </>
+        )
+    }
+} 

+ 2 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx

@@ -29,6 +29,7 @@ import { AbstractMesh } from 'babylonjs/Meshes/abstractMesh';
 import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
 import { TextInputLineComponent } from '../../../lines/textInputLineComponent';
 import { AnimationGridComponent } from '../animations/animationPropertyGridComponent';
+import { RenderingManager } from 'babylonjs/Rendering/renderingManager';
 
 interface IMeshPropertyGridComponentProps {
     globalState: GlobalState;
@@ -389,6 +390,7 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                         !mesh.parent &&
                         <CheckBoxLineComponent label="Infinite distance" target={mesh} propertyName="infiniteDistance" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
+                    <SliderLineComponent label="Rendering group ID" decimalCount={0} target={mesh} propertyName="renderingGroupId" minimum={RenderingManager.MIN_RENDERINGGROUPS} maximum={RenderingManager.MAX_RENDERINGGROUPS - 1} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />                    
                 </LineContainerComponent>
                 {
                     mesh.morphTargetManager != null &&

+ 55 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/sprites/spriteManagerPropertyGridComponent.tsx

@@ -0,0 +1,55 @@
+import * as React from "react";
+
+import { Observable } from "babylonjs/Misc/observable";
+
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { LockObject } from "../lockObject";
+import { LineContainerComponent } from '../../../lineContainerComponent';
+import { GlobalState } from '../../../../globalState';
+import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+import { TextInputLineComponent } from '../../../lines/textInputLineComponent';
+import { TextLineComponent } from '../../../lines/textLineComponent';
+import { CheckBoxLineComponent } from '../../../lines/checkBoxLineComponent';
+import { FloatLineComponent } from '../../../lines/floatLineComponent';
+import { SliderLineComponent } from '../../../lines/sliderLineComponent';
+import { RenderingManager } from 'babylonjs/Rendering/renderingManager';
+import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
+
+interface ISpriteManagerPropertyGridComponentProps {
+    globalState: GlobalState;
+    spriteManager: SpriteManager;
+    lockObject: LockObject;
+    onSelectionChangedObservable?: Observable<any>;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class SpriteManagerPropertyGridComponent extends React.Component<ISpriteManagerPropertyGridComponentProps> {
+    constructor(props: ISpriteManagerPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const spriteManager = this.props.spriteManager;
+
+        return (
+            <div className="pane">
+                <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Name" target={spriteManager} propertyName="name" onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                    <TextLineComponent label="Unique ID" value={spriteManager.uniqueId.toString()} />
+                    <FloatLineComponent label="Capacity" isInteger={true} target={spriteManager} propertyName="capacity" />
+                    <TextureLinkLineComponent label="Texture" texture={spriteManager.texture} onSelectionChangedObservable={this.props.onSelectionChangedObservable}/>
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="PROPERTIES">
+                    <CheckBoxLineComponent label="Pickable" target={spriteManager} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Fog enabled" target={spriteManager} propertyName="fogEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="No depth write" target={spriteManager} propertyName="disableDepthWrite" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Rendering group ID" decimalCount={0} target={spriteManager} propertyName="renderingGroupId" minimum={RenderingManager.MIN_RENDERINGGROUPS} maximum={RenderingManager.MAX_RENDERINGGROUPS - 1} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="DEFAULT SIZE">
+                    <FloatLineComponent label="Cell width" isInteger={true} target={spriteManager} propertyName="cellWidth" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                    <FloatLineComponent label="Cell height" isInteger={true} target={spriteManager} propertyName="cellHeight" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 84 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/sprites/spritePropertyGridComponent.tsx

@@ -0,0 +1,84 @@
+import * as React from "react";
+
+import { Observable } from "babylonjs/Misc/observable";
+
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { LockObject } from "../lockObject";
+import { LineContainerComponent } from '../../../lineContainerComponent';
+import { GlobalState } from '../../../../globalState';
+import { TextInputLineComponent } from '../../../lines/textInputLineComponent';
+import { TextLineComponent } from '../../../lines/textLineComponent';
+import { Sprite } from 'babylonjs/Sprites/sprite';
+import { CheckBoxLineComponent } from '../../../lines/checkBoxLineComponent';
+import { Vector3LineComponent } from '../../../lines/vector3LineComponent';
+import { Color4LineComponent } from '../../../lines/color4LineComponent';
+import { FloatLineComponent } from '../../../lines/floatLineComponent';
+import { SliderLineComponent } from '../../../lines/sliderLineComponent';
+
+interface ISpritePropertyGridComponentProps {
+    globalState: GlobalState;
+    sprite: Sprite;
+    lockObject: LockObject;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;    
+    onSelectionChangedObservable?: Observable<any>;
+}
+
+export class SpritePropertyGridComponent extends React.Component<ISpritePropertyGridComponentProps> {
+    constructor(props: ISpritePropertyGridComponentProps) {
+        super(props);
+    }
+
+    onManagerLink() {
+        if (!this.props.onSelectionChangedObservable) {
+            return;
+        }
+
+        
+        const sprite = this.props.sprite;
+        this.props.onSelectionChangedObservable.notifyObservers(sprite.manager);
+    }
+
+    render() {
+        const sprite = this.props.sprite;
+        const manager = sprite.manager;
+        const textureSize = manager.texture.getSize();
+        let maxCellCount = 0;
+        
+        if (!textureSize.width || !textureSize.height) {
+            maxCellCount = Math.max(sprite.fromIndex, sprite.toIndex);
+        } else {
+            maxCellCount = (textureSize.width / manager.cellWidth) * (textureSize.height / manager.cellHeight);
+        }
+
+        return (
+            <div className="pane">
+                <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Name" target={sprite} propertyName="name" onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                    <TextLineComponent label="Unique ID" value={sprite.uniqueId.toString()} />
+                    <TextLineComponent label="Link to manager" value={manager.name} onLink={() => this.onManagerLink()} />
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="PROPERTIES">
+                    <Vector3LineComponent label="Position" target={sprite} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Pickable" target={sprite} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Use alpha for picking" target={sprite} propertyName="useAlphaForPicking" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color4LineComponent label="Color" target={sprite} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent useEuler={this.props.globalState.onlyUseEulers} label="Angle" target={sprite} propertyName="angle" minimum={0} maximum={2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="CELL">
+                    <CheckBoxLineComponent label="Invert U axis" target={sprite} propertyName="invertU" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Invert V axis" target={sprite} propertyName="invertV" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="SCALE">
+                    <FloatLineComponent label="Width" target={sprite} propertyName="width" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                    <FloatLineComponent label="Height" target={sprite} propertyName="height" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="ANIMATION">
+                    <SliderLineComponent label="Start cell" decimalCount={0} target={sprite} propertyName="fromIndex" minimum={0} maximum={maxCellCount} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="End cell" decimalCount={0} target={sprite} propertyName="toIndex" minimum={0} maximum={maxCellCount} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Loop" target={sprite} propertyName="loopAnimation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Delay" target={sprite} propertyName="delay" digits={0} min={0} isInteger={true} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 30 - 0
inspector/src/components/sceneExplorer/entities/spriteManagerTreeItemComponent.tsx

@@ -0,0 +1,30 @@
+import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+
+import { faAddressBook } from '@fortawesome/free-solid-svg-icons';
+import { TreeItemLabelComponent } from "../treeItemLabelComponent";
+import { ExtensionsComponent } from "../extensionsComponent";
+import * as React from 'react';
+import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+
+interface ISpriteManagerTreeItemComponentProps {
+    spriteManager: SpriteManager,
+    extensibilityGroups?: IExplorerExtensibilityGroup[],
+    onClick: () => void
+}
+
+export class SpriteManagerTreeItemComponent extends React.Component<ISpriteManagerTreeItemComponentProps> {
+    constructor(props: ISpriteManagerTreeItemComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <div className="spriteManagerTools">
+                <TreeItemLabelComponent label={this.props.spriteManager.name || "No name"} onClick={() => this.props.onClick()} icon={faAddressBook} color="blanchedalmond" />
+                {
+                    <ExtensionsComponent target={this.props.spriteManager} extensibilityGroups={this.props.extensibilityGroups} />
+                }
+            </div>
+        )
+    }
+}

+ 30 - 0
inspector/src/components/sceneExplorer/entities/spriteTreeItemComponent.tsx

@@ -0,0 +1,30 @@
+import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+
+import { faGhost } from '@fortawesome/free-solid-svg-icons';
+import { TreeItemLabelComponent } from "../treeItemLabelComponent";
+import { ExtensionsComponent } from "../extensionsComponent";
+import * as React from 'react';
+import { Sprite } from 'babylonjs/Sprites/sprite';
+
+interface ISpriteTreeItemComponentProps {
+    sprite: Sprite,
+    extensibilityGroups?: IExplorerExtensibilityGroup[],
+    onClick: () => void
+}
+
+export class SpriteTreeItemComponent extends React.Component<ISpriteTreeItemComponentProps> {
+    constructor(props: ISpriteTreeItemComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <div className="spriteTools">
+                <TreeItemLabelComponent label={this.props.sprite.name || "No name"} onClick={() => this.props.onClick()} icon={faGhost} color="blanchedalmond" />
+                {
+                    <ExtensionsComponent target={this.props.sprite} extensibilityGroups={this.props.extensibilityGroups} />
+                }
+            </div>
+        )
+    }
+}

+ 25 - 1
inspector/src/components/sceneExplorer/sceneExplorer.scss

@@ -415,7 +415,31 @@
                 width: 20px;
                 grid-column: 3;
             }
-        }
+        }        
+        
+        .spriteTools {
+            grid-column: 2;
+            display: grid;
+            grid-template-columns: 1fr auto 5px;
+            align-items: center;
+
+            .extensions {
+                width: 20px;
+                grid-column: 2;
+            }
+        }   
+
+        .spriteManagerTools {
+            grid-column: 2;
+            display: grid;
+            grid-template-columns: 1fr auto 5px;
+            align-items: center;
+
+            .extensions {
+                width: 20px;
+                grid-column: 2;
+            }
+        }        
 
         .materialTools {
             grid-column: 2;

+ 15 - 0
inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx

@@ -24,6 +24,7 @@ import { GPUParticleSystem } from 'babylonjs/Particles/gpuParticleSystem';
 import { SSAO2RenderingPipeline } from 'babylonjs/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline';
 import { StandardMaterial } from 'babylonjs/Materials/standardMaterial';
 import { PBRMaterial } from 'babylonjs/Materials/PBR/pbrMaterial';
+import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
 
 require("./sceneExplorer.scss");
 
@@ -355,6 +356,16 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
             materials.push(...scene.multiMaterials);
         }
 
+        // Sprite Managers
+        let spriteManagersContextMenus: { label: string, action: () => void }[] = [];
+        spriteManagersContextMenus.push({
+            label: "Add new sprite manager",
+            action: () => {
+                let newSpriteManager = new SpriteManager("Default sprite manager", "//playground.babylonjs.com/textures/player.png", 2, 64, scene);
+                this.props.globalState.onSelectionChangedObservable.notifyObservers(newSpriteManager);
+            }
+        });            
+
         // Particle systems
         let particleSystemsContextMenus: { label: string, action: () => void }[] = [];
         particleSystemsContextMenus.push({
@@ -405,6 +416,10 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
                 <TreeItemComponent globalState={this.props.globalState} 
                     contextMenuItems={particleSystemsContextMenus} 
                     extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.particleSystems} label="Particle systems" offset={1} filter={this.state.filter} />
+                <TreeItemComponent globalState={this.props.globalState} 
+                    contextMenuItems={spriteManagersContextMenus} 
+                    forceSubitems={true}
+                    extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.spriteManagers} label="Sprite managers" offset={1} filter={this.state.filter} />
                 {
                     guiElements && guiElements.length > 0 &&
                     <TreeItemComponent globalState={this.props.globalState} extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={guiElements} label="GUI" offset={1} filter={this.state.filter} />

+ 13 - 8
inspector/src/components/sceneExplorer/treeItemComponent.tsx

@@ -77,7 +77,8 @@ export interface ITreeItemComponentProps {
     items?: Nullable<any[]>,
     label: string,
     offset: number,
-    filter: Nullable<string>,
+    filter: Nullable<string>,    
+    forceSubitems?: boolean,
     globalState: GlobalState,
     entity?: any,
     selectedEntity: any,
@@ -145,20 +146,24 @@ export class TreeItemComponent extends React.Component<ITreeItemComponentProps,
     }
 
     render() {
-        const items = this.props.items;
+        let items = this.props.items;
 
         const marginStyle = {
             paddingLeft: (10 * (this.props.offset + 0.5)) + "px"
         }
 
         if (!items) {
-            return (
-                <div className="groupContainer" style={marginStyle}>
-                    <div>
-                        {this.props.label}
+            if (this.props.forceSubitems) {
+                items = [];
+            } else {
+                return (
+                    <div className="groupContainer" style={marginStyle}>
+                        <div>
+                            {this.props.label}
+                        </div>
                     </div>
-                </div>
-            )
+                )
+            }
         }
 
         if (!items.length) {

+ 12 - 0
inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx

@@ -32,6 +32,10 @@ import { BoneTreeItemComponent } from './entities/boneTreeItemComponent';
 import { Bone } from 'babylonjs/Bones/bone';
 import { ParticleSystemTreeItemComponent } from './entities/particleSystemTreeItemComponent';
 import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+import { SpriteManagerTreeItemComponent } from './entities/spriteManagerTreeItemComponent';
+import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
+import { SpriteTreeItemComponent } from './entities/spriteTreeItemComponent';
+import { Sprite } from 'babylonjs/Sprites/sprite';
 
 
 interface ITreeItemSpecializedComponentProps {
@@ -70,6 +74,14 @@ export class TreeItemSpecializedComponent extends React.Component<ITreeItemSpeci
                 }
             }
 
+            if (className.indexOf("SpriteManager") !== -1) {
+                return (<SpriteManagerTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} spriteManager={entity as SpriteManager} onClick={() => this.onClick()} />);
+            }
+
+            if (className.indexOf("Sprite") !== -1) {
+                return (<SpriteTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} sprite={entity as Sprite} onClick={() => this.onClick()} />);
+            }
+
             if (className.indexOf("Skeleton") !== -1) {
                 return (<SkeletonTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} skeleton={entity as Skeleton} onClick={() => this.onClick()} />);
             }

+ 1 - 1
src/Bones/skeleton.ts

@@ -285,7 +285,7 @@ export class Skeleton implements IAnimatable {
      * @returns the requested animation range or null if not found
      */
     public getAnimationRange(name: string): Nullable<AnimationRange> {
-        return this._ranges[name];
+        return this._ranges[name] || null;
     }
 
     /**

+ 7 - 0
src/Materials/standardMaterial.ts

@@ -120,6 +120,10 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public ALPHATEST_AFTERALLALPHACOMPUTATIONS = false;
     public ALPHABLEND = true;
 
+    public RGBDLIGHTMAP = false;
+    public RGBDREFLECTION = false;
+    public RGBDREFRACTION = false;
+
     public IMAGEPROCESSING = false;
     public VIGNETTE = false;
     public VIGNETTEBLENDMODEMULTIPLY = false;
@@ -856,6 +860,7 @@ export class StandardMaterial extends PushMaterial {
                         defines.REFLECTIONOVERALPHA = this._useReflectionOverAlpha;
                         defines.INVERTCUBICMAP = (this._reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE);
                         defines.REFLECTIONMAP_3D = this._reflectionTexture.isCube;
+                        defines.RGBDREFLECTION = this._reflectionTexture.isRGBD;
 
                         switch (this._reflectionTexture.coordinatesMode) {
                             case Texture.EXPLICIT_MODE:
@@ -911,6 +916,7 @@ export class StandardMaterial extends PushMaterial {
                     } else {
                         MaterialHelper.PrepareDefinesForMergedUV(this._lightmapTexture, defines, "LIGHTMAP");
                         defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
+                        defines.RGBDLIGHTMAP = this._lightmapTexture.isRGBD;
                     }
                 } else {
                     defines.LIGHTMAP = false;
@@ -951,6 +957,7 @@ export class StandardMaterial extends PushMaterial {
                         defines.REFRACTION = true;
 
                         defines.REFRACTIONMAP_3D = this._refractionTexture.isCube;
+                        defines.RGBDREFRACTION = this._refractionTexture.isRGBD;
                     }
                 } else {
                     defines.REFRACTION = false;

+ 2 - 1
src/Meshes/mesh.ts

@@ -1774,7 +1774,8 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
         var sideOrientation: Nullable<number>;
 
-        if (!instanceDataStorage.isFrozen && this._effectiveMaterial.backFaceCulling) {
+        if (!instanceDataStorage.isFrozen &&
+            (this._effectiveMaterial.backFaceCulling || this.overrideMaterialSideOrientation !== null)) {
             let mainDeterminant = effectiveMesh._getWorldMatrixDeterminant();
             sideOrientation = this.overrideMaterialSideOrientation;
             if (sideOrientation == null) {

+ 11 - 1
src/Shaders/default.fragment.fx

@@ -254,7 +254,11 @@ void main(void) {
 	float shadow = 1.;
 
 #ifdef LIGHTMAP
-	vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV + uvOffset).rgb * vLightmapInfos.y;
+	vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV + uvOffset).rgb;
+    #ifdef RGBDLIGHTMAP
+        lightmapColor.rgb = fromRGBD(lightmapColor);
+    #endif
+	lightmapColor.rgb *= vLightmapInfos.y
 #endif
 
 #include<lightFragment>[0..maxSimultaneousLights]
@@ -279,6 +283,9 @@ void main(void) {
 		
 		refractionColor = texture2D(refraction2DSampler, refractionCoords).rgb;
 	#endif
+    #ifdef RGBDREFRACTION
+        refractionColor.rgb = fromRGBD(refractionColor);
+    #endif
 	#ifdef IS_REFRACTION_LINEAR
 		refractionColor = toGammaSpace(refractionColor);
 	#endif
@@ -317,6 +324,9 @@ vec3 reflectionColor = vec3(0., 0., 0.);
 		coords.y = 1.0 - coords.y;
 		reflectionColor = texture2D(reflection2DSampler, coords).rgb;
 	#endif
+    #ifdef RGBDREFLECTION
+        reflectionColor.rgb = fromRGBD(reflectionColor);
+    #endif
 	#ifdef IS_REFLECTION_LINEAR
 		reflectionColor = toGammaSpace(reflectionColor);
 	#endif

+ 64 - 5
src/Sprites/sprite.ts

@@ -4,12 +4,14 @@ import { ActionManager } from "../Actions/actionManager";
 import { ISpriteManager } from "./spriteManager";
 import { Color4 } from '../Maths/math.color';
 import { Observable } from '../Misc/observable';
+import { IAnimatable } from '../Animations/animatable.interface';
+declare type Animation = import("../Animations/animation").Animation;
 
 /**
  * Class used to represent a sprite
  * @see http://doc.babylonjs.com/babylon101/sprites
  */
-export class Sprite {
+export class Sprite implements IAnimatable {
     /** Gets or sets the current world position */
     public position: Vector3;
     /** Gets or sets the main color */
@@ -25,13 +27,13 @@ export class Sprite {
     /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
     public cellRef: string;
     /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
-    public invertU = 0;
+    public invertU = false;
     /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
-    public invertV = 0;
+    public invertV = false;
     /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
     public disposeWhenFinishedAnimating: boolean;
     /** Gets the list of attached animations */
-    public animations = new Array<Animation>();
+    public animations: Nullable<Array<Animation>> = new Array<Animation>();
     /** Gets or sets a boolean indicating if the sprite can be picked */
     public isPickable = false;
     /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
@@ -83,6 +85,18 @@ export class Sprite {
     }
 
     /**
+     * Gets or sets the unique id of the sprite
+     */
+    public uniqueId: number;
+
+    /**
+     * Gets the manager of this sprite
+     */
+    public get manager() {
+        return this._manager;
+    }
+
+    /**
      * Creates a new Sprite
      * @param name defines the name
      * @param manager defines the manager
@@ -94,11 +108,56 @@ export class Sprite {
         this._manager = manager;
 
         this._manager.sprites.push(this);
+        this.uniqueId = this._manager.scene.getUniqueId();
 
         this.position = Vector3.Zero();
     }
 
     /**
+     * Returns the string "Sprite"
+     * @returns "Sprite"
+     */
+    public getClassName(): string {
+        return "Sprite";
+    }
+
+    /** Gets or sets the initial key for the animation (setting it will restart the animation)  */
+    public get fromIndex() {
+        return this._fromIndex;
+    }
+
+    public set fromIndex(value: number) {
+        this.playAnimation(value, this._toIndex, this._loopAnimation, this._delay, this._onAnimationEnd);
+    }
+
+    /** Gets or sets the end key for the animation (setting it will restart the animation)  */
+    public get toIndex() {
+        return this._toIndex;
+    }
+
+    public set toIndex(value: number) {
+        this.playAnimation(this._fromIndex, value, this._loopAnimation, this._delay, this._onAnimationEnd);
+    }
+
+    /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */
+    public get loopAnimation() {
+        return this._loopAnimation;
+    }
+
+    public set loopAnimation(value: boolean) {
+        this.playAnimation(this._fromIndex, this._toIndex, value, this._delay, this._onAnimationEnd);
+    }
+
+    /** Gets or sets the delay between cell changes (setting it will restart the animation)  */
+    public get delay() {
+        return Math.max(this._delay, 1);
+    }
+
+    public set delay(value: number) {
+        this.playAnimation(this._fromIndex, this._toIndex, this._loopAnimation, value, this._onAnimationEnd);
+    }
+
+    /**
      * Starts an animation
      * @param from defines the initial key
      * @param to defines the end key
@@ -110,7 +169,7 @@ export class Sprite {
         this._fromIndex = from;
         this._toIndex = to;
         this._loopAnimation = loop;
-        this._delay = delay;
+        this._delay = delay || 1;
         this._animationStarted = true;
 
         if (from < to) {

+ 83 - 3
src/Sprites/spriteManager.ts

@@ -18,12 +18,19 @@ import { Logger } from "../Misc/logger";
 import "../Shaders/sprites.fragment";
 import "../Shaders/sprites.vertex";
 import { DataBuffer } from '../Meshes/dataBuffer';
+import { Engine } from '../Engines/engine';
 declare type Ray = import("../Culling/ray").Ray;
 
 /**
  * Defines the minimum interface to fullfil in order to be a sprite manager.
  */
 export interface ISpriteManager extends IDisposable {
+
+    /**
+     * Gets manager's name
+     */
+    name: string;
+
     /**
      * Restricts the camera to viewing objects with the same layerMask.
      * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0
@@ -36,6 +43,11 @@ export interface ISpriteManager extends IDisposable {
     isPickable: boolean;
 
     /**
+     * Gets the hosting scene
+     */
+    scene: Scene;
+
+    /**
      * Specifies the rendering group id for this mesh (0 by default)
      * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
      */
@@ -47,6 +59,16 @@ export interface ISpriteManager extends IDisposable {
     sprites: Array<Sprite>;
 
     /**
+     * Gets or sets the spritesheet texture
+     */
+    texture: Texture;
+
+    /** Defines the default width of a cell in the spritesheet */
+    cellWidth: number;
+    /** Defines the default height of a cell in the spritesheet */
+    cellHeight: number;
+
+    /**
      * Tests the intersection of a sprite with a specific ray.
      * @param ray The ray we are sending to test the collision
      * @param camera The camera space we are sending rays in
@@ -132,6 +154,36 @@ export class SpriteManager implements ISpriteManager {
     private _effectFog: Effect;
 
     /**
+     * Gets or sets the unique id of the sprite
+     */
+    public uniqueId: number;
+
+    /**
+     * Gets the array of sprites
+     */
+    public get children() {
+        return this.sprites;
+    }
+
+    /**
+     * Gets the hosting scene
+     */
+    public get scene() {
+        return this._scene;
+    }
+
+    /**
+     * Gets or sets the capacity of the manager
+     */
+    public get capacity() {
+        return this._capacity;
+    }
+
+    public set capacity(value: number) {
+        this._capacity = value;
+    }
+
+    /**
      * Gets or sets the spritesheet texture
      */
     public get texture(): Texture {
@@ -196,8 +248,9 @@ export class SpriteManager implements ISpriteManager {
         }
 
         this._epsilon = epsilon;
-        this._scene = scene;
+        this._scene = scene || Engine.LastCreatedScene;
         this._scene.spriteManagers.push(this);
+        this.uniqueId = this.scene.getUniqueId();
 
         var indices = [];
         var index = 0;
@@ -246,6 +299,14 @@ export class SpriteManager implements ISpriteManager {
         }
     }
 
+    /**
+     * Returns the string "SpriteManager"
+     * @returns "SpriteManager"
+     */
+    public getClassName(): string {
+        return "SpriteManager";
+    }
+
     private _makePacked(imgUrl: string, spriteJSON: any) {
         if (spriteJSON !== null) {
             try {
@@ -343,8 +404,15 @@ export class SpriteManager implements ISpriteManager {
         this._vertexData[arrayOffset + 5] = sprite.height;
         this._vertexData[arrayOffset + 6] = offsetX;
         this._vertexData[arrayOffset + 7] = offsetY;
-        // Inverts
-        this._vertexData[arrayOffset + 8] = sprite.invertU ? 1 : 0;
+
+        // Inverts according to Right Handed
+        if (this._scene.useRightHandedSystem) {
+            this._vertexData[arrayOffset + 8] = sprite.invertU ? 0 : 1;
+        }
+        else {
+            this._vertexData[arrayOffset + 8] = sprite.invertU ? 1 : 0;
+        }
+
         this._vertexData[arrayOffset + 9] = sprite.invertV ? 1 : 0;
         // CellIfo
         if (this._packedAndReady) {
@@ -633,6 +701,13 @@ export class SpriteManager implements ISpriteManager {
         // VBOs
         engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
 
+        // Handle Right Handed
+        const culling = engine.depthCullingState.cull || true;
+        const zOffset = engine.depthCullingState.zOffset;
+        if (this._scene.useRightHandedSystem) {
+            engine.setState(culling, zOffset, false, false);
+        }
+
         // Draw order
         engine.setDepthFunctionToLessOrEqual();
         if (!this.disableDepthWrite) {
@@ -646,6 +721,11 @@ export class SpriteManager implements ISpriteManager {
         engine.setAlphaMode(this._blendMode);
         engine.drawElementsType(Material.TriangleFillMode, 0, (offset / 4) * 6);
         engine.setAlphaMode(Constants.ALPHA_DISABLE);
+
+        // Restore Right Handed
+        if (this._scene.useRightHandedSystem) {
+            engine.setState(culling, zOffset, false, true);
+        }
     }
 
     /**

+ 1 - 1
src/node.ts

@@ -679,7 +679,7 @@ export class Node implements IBehaviorAware<Node> {
      * @returns null if not found else the requested animation range
      */
     public getAnimationRange(name: string): Nullable<AnimationRange> {
-        return this._ranges[name];
+        return this._ranges[name] || null;
     }
 
     /**