Browse Source

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

sebavan 5 years ago
parent
commit
20f267d2f1
80 changed files with 4369 additions and 2506 deletions
  1. 1 1
      dist/preview release/babylon.js
  2. 5 2
      dist/preview release/babylon.max.js
  3. 1 1
      dist/preview release/babylon.max.js.map
  4. 9 5
      dist/preview release/documentation.d.ts
  5. 3 3
      dist/preview release/inspector/babylon.inspector.bundle.js
  6. 603 314
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  7. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  8. 48 23
      dist/preview release/inspector/babylon.inspector.d.ts
  9. 113 63
      dist/preview release/inspector/babylon.inspector.module.d.ts
  10. 6 6
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  11. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.js.map
  12. 7 7
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  13. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.js.map
  14. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  15. 6 6
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  16. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js.map
  17. 6 6
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  18. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.js.map
  19. 6 6
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js.map
  21. 6 6
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  22. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js.map
  23. 6 6
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js.map
  25. 6 6
      dist/preview release/materialsLibrary/babylon.mixMaterial.js
  26. 1 1
      dist/preview release/materialsLibrary/babylon.mixMaterial.js.map
  27. 6 6
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.js.map
  29. 6 6
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js.map
  31. 6 6
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  32. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js.map
  33. 6 6
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  34. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.js.map
  35. 6 6
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js.map
  37. 6 6
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js.map
  39. 6 6
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.js.map
  41. 49 49
      dist/preview release/materialsLibrary/babylonjs.materials.js
  42. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js.map
  43. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  44. 1 1
      dist/preview release/packagesSizeBaseLine.json
  45. 24 1
      dist/preview release/sandbox/babylon.sandbox.d.ts
  46. 6 6
      dist/preview release/sandbox/babylon.sandbox.js
  47. 243 8
      dist/preview release/sandbox/babylon.sandbox.max.js
  48. 1 1
      dist/preview release/sandbox/babylon.sandbox.max.js.map
  49. 51 2
      dist/preview release/sandbox/babylon.sandbox.module.d.ts
  50. 10 6
      dist/preview release/viewer/babylon.module.d.ts
  51. 10 10
      dist/preview release/viewer/babylon.viewer.js
  52. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  53. 2 1
      dist/preview release/what's new.md
  54. 8 2
      inspector/src/components/actionTabs/lineContainerComponent.tsx
  55. 21 15
      inspector/src/components/actionTabs/lines/iconButtonLineComponent.tsx
  56. 346 253
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/addAnimation.tsx
  57. 1380 1033
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx
  58. 300 209
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationPropertyGridComponent.tsx
  59. 132 55
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss
  60. 29 28
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/editorControls.tsx
  61. 85 47
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx
  62. 72 19
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/playhead.tsx
  63. 290 184
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/timeline.tsx
  64. 3 3
      inspector/src/components/globalState.ts
  65. 1 1
      materialsLibrary/src/custom/customMaterial.ts
  66. 1 1
      materialsLibrary/src/custom/pbrCustomMaterial.ts
  67. 2 0
      sandbox/index.css
  68. 1 1
      sandbox/public/index.html
  69. 162 0
      sandbox/src/components/animationBar.tsx
  70. 30 8
      sandbox/src/components/dropUpButton.tsx
  71. 4 2
      sandbox/src/components/footer.tsx
  72. 1 0
      sandbox/src/img/icon-down.svg
  73. 1 0
      sandbox/src/img/icon-pause.svg
  74. 1 0
      sandbox/src/img/icon-play.svg
  75. 1 0
      sandbox/src/img/icon-up.svg
  76. 4 1
      sandbox/src/sandbox.tsx
  77. 129 0
      sandbox/src/scss/animationBar.scss
  78. 66 32
      sandbox/src/scss/footer.scss
  79. 1 1
      sandbox/src/tools/environmentTools.ts
  80. 6 2
      src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts

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


+ 5 - 2
dist/preview release/babylon.max.js

@@ -163495,6 +163495,10 @@ var DefaultRenderingPipeline = /** @class */ (function (_super) {
         });
         _this._imageProcessingConfigurationObserver = _this._scene.imageProcessingConfiguration.onUpdateParameters.add(function () {
             _this.bloom._downscale._exposure = _this._scene.imageProcessingConfiguration.exposure;
+            if (_this.imageProcessingEnabled !== _this._scene.imageProcessingConfiguration.isEnabled) {
+                _this._imageProcessingEnabled = _this._scene.imageProcessingConfiguration.isEnabled;
+                _this._buildPipeline();
+            }
         });
         _this._buildPipeline();
         return _this;
@@ -163708,8 +163712,7 @@ var DefaultRenderingPipeline = /** @class */ (function (_super) {
             if (this._imageProcessingEnabled === enabled) {
                 return;
             }
-            this._imageProcessingEnabled = enabled;
-            this._buildPipeline();
+            this._scene.imageProcessingConfiguration.isEnabled = enabled;
         },
         enumerable: true,
         configurable: true

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


File diff suppressed because it is too large
+ 9 - 5
dist/preview release/documentation.d.ts


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


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


+ 48 - 23
dist/preview release/inspector/babylon.inspector.d.ts

@@ -52,6 +52,7 @@ declare module INSPECTOR {
         };
         blockMutationUpdates: boolean;
         selectedLineContainerTitles: Array<string>;
+        selectedLineContainerTitlesNoFocus: Array<string>;
         recorder: ReplayRecorder;
         private _onlyUseEulers;
         get onlyUseEulers(): boolean;
@@ -647,7 +648,10 @@ declare module INSPECTOR {
     }> {
         readonly _frames: object[];
         private _scrollable;
+        private _scrollbarHandle;
         private _direction;
+        private _scrolling;
+        private _shiftX;
         constructor(props: ITimelineProps);
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
@@ -664,6 +668,12 @@ declare module INSPECTOR {
         isFrameBeingUsed(frame: number, direction: number): number | false;
         dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
         dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        scrollDragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDrag(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         render(): JSX.Element;
     }
 }
@@ -671,9 +681,19 @@ declare module INSPECTOR {
     interface IPlayheadProps {
         frame: number;
         offset: number;
+        onCurrentFrameChange: (frame: number) => void;
     }
     export class Playhead extends React.Component<IPlayheadProps> {
+        private _direction;
+        private _active;
         constructor(props: IPlayheadProps);
+        dragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        dragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<HTMLDivElement>): void;
+        drag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        dragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        calculateMove(): string;
         render(): JSX.Element;
     }
 }
@@ -883,6 +903,7 @@ declare module INSPECTOR {
         playheadPos: number;
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
+        selectedCoordinate: number;
     }> {
         private _heightScale;
         readonly _entityName: string;
@@ -890,37 +911,38 @@ declare module INSPECTOR {
         private _svgKeyframes;
         private _isPlaying;
         private _graphCanvas;
-        private _selectedCurve;
         private _svgCanvas;
         private _isTargetedAnimation;
+        private _onBeforeRenderObserver;
+        private _mainAnimatable;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         /**
-        * Notifications
-        * To add notification we set the state and clear to make the notification bar hide.
-        */
+         * Notifications
+         * To add notification we set the state and clear to make the notification bar hide.
+         */
         clearNotification(): void;
         /**
-        * Zoom and Scroll
-        * This section handles zoom and scroll
-        * of the graph area.
-        */
+         * Zoom and Scroll
+         * This section handles zoom and scroll
+         * of the graph area.
+         */
         zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
         resetPlayheadOffset(): void;
         /**
-        * Keyframe Manipulation
-        * This section handles events from SvgDraggableArea.
-        */
+         * Keyframe Manipulation
+         * This section handles events from SvgDraggableArea.
+         */
         selectKeyframe(id: string): void;
         selectedControlPoint(type: string, id: string): void;
         updateValuePerCoordinate(dataType: number, value: number | BABYLON.Vector2 | BABYLON.Vector3 | BABYLON.Color3 | BABYLON.Color4 | BABYLON.Size | BABYLON.Quaternion, newValue: number, coordinate?: number): number | BABYLON.Vector3 | BABYLON.Quaternion | BABYLON.Color3 | BABYLON.Color4 | BABYLON.Vector2 | BABYLON.Size;
         renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, id: string): void;
         /**
-        * Actions
-        * This section handles events from GraphActionsBar.
-        */
+         * Actions
+         * This section handles events from GraphActionsBar.
+         */
         handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
         setFlatTangent(): void;
@@ -931,9 +953,9 @@ declare module INSPECTOR {
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         /**
-        * Curve Rendering Functions
-        * This section handles how to render curves.
-        */
+         * Curve Rendering Functions
+         * This section handles how to render curves.
+         */
         linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: BABYLON.Vector2, index: number): void;
         flatTangents(keyframes: BABYLON.IAnimationKey[], dataType: number): BABYLON.IAnimationKey[];
@@ -958,20 +980,23 @@ declare module INSPECTOR {
         setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
         /**
-        * Core functions
-        * This section handles main Curve Editor Functions.
-        */
+         * Core functions
+         * This section handles main Curve Editor Functions.
+         */
         selectAnimation(animation: BABYLON.Animation, coordinate?: SelectedCoordinate): void;
         isAnimationPlaying(): boolean;
         playStopAnimation(): boolean;
         analizeAnimationForLerp(animation: BABYLON.Animation | null): boolean;
         /**
-        * Timeline
-        * This section controls the timeline.
-        */
+         * Timeline
+         * This section controls the timeline.
+         */
         changeCurrentFrame(frame: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
+        moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
+        registerObs(): void;
+        componentWillUnmount(): void;
         render(): JSX.Element;
     }
 }

+ 113 - 63
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -65,6 +65,7 @@ declare module "babylonjs-inspector/components/globalState" {
         };
         blockMutationUpdates: boolean;
         selectedLineContainerTitles: Array<string>;
+        selectedLineContainerTitlesNoFocus: Array<string>;
         recorder: ReplayRecorder;
         private _onlyUseEulers;
         get onlyUseEulers(): boolean;
@@ -672,7 +673,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/lines/iconButtonLineComponent" {
-    import * as React from "react";
+    import * as React from 'react';
     export interface IIconButtonLineComponentProps {
         icon: string;
         onClick: () => void;
@@ -711,7 +712,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/timeline" {
-    import * as React from "react";
+    import * as React from 'react';
     import { IAnimationKey } from 'babylonjs/Animations/animationKey';
     interface ITimelineProps {
         keyframes: IAnimationKey[] | null;
@@ -728,7 +729,10 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }> {
         readonly _frames: object[];
         private _scrollable;
+        private _scrollbarHandle;
         private _direction;
+        private _scrolling;
+        private _shiftX;
         constructor(props: ITimelineProps);
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
@@ -745,17 +749,33 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         isFrameBeingUsed(frame: number, direction: number): number | false;
         dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
         dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        scrollDragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDrag(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         render(): JSX.Element;
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/playhead" {
-    import * as React from "react";
+    import * as React from 'react';
     interface IPlayheadProps {
         frame: number;
         offset: number;
+        onCurrentFrameChange: (frame: number) => void;
     }
     export class Playhead extends React.Component<IPlayheadProps> {
+        private _direction;
+        private _active;
         constructor(props: IPlayheadProps);
+        dragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        dragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<HTMLDivElement>): void;
+        drag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        dragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        calculateMove(): string;
         render(): JSX.Element;
     }
 }
@@ -772,7 +792,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar" {
-    import * as React from "react";
+    import * as React from 'react';
     interface IGraphActionsBarProps {
         addKeyframe: () => void;
         removeKeyframe: () => void;
@@ -795,8 +815,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/addAnimation" {
-    import * as React from "react";
-    import { Observable } from "babylonjs/Misc/observable";
+    import * as React from 'react';
+    import { Observable } from 'babylonjs/Misc/observable';
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
     import { Animation } from 'babylonjs/Animations/animation';
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
@@ -922,13 +942,13 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/editorControls" {
-    import * as React from "react";
-    import { Observable } from "babylonjs/Misc/observable";
+    import * as React from 'react';
+    import { Observable } from 'babylonjs/Misc/observable';
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
-    import { Animation } from "babylonjs/Animations/animation";
+    import { Animation } from 'babylonjs/Animations/animation';
     import { SelectedCoordinate } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/animationListTree";
-    import { IAnimatable } from "babylonjs/Animations/animatable.interface";
-    import { TargetedAnimation } from "babylonjs/Animations/animationGroup";
+    import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
+    import { TargetedAnimation } from 'babylonjs/Animations/animationGroup';
     import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
     interface IEditorControlsProps {
         isTargetedAnimation: boolean;
@@ -958,7 +978,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent" {
-    import * as React from "react";
+    import * as React from 'react';
     import { Animation } from 'babylonjs/Animations/animation';
     import { Vector2, Vector3, Quaternion } from 'babylonjs/Maths/math.vector';
     import { Color3, Color4 } from 'babylonjs/Maths/math.color';
@@ -966,9 +986,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     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 { Scene } from 'babylonjs/scene';
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
-    import { TargetedAnimation } from "babylonjs/Animations/animationGroup";
+    import { TargetedAnimation } from 'babylonjs/Animations/animationGroup';
     import { SelectedCoordinate } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/animationListTree";
     import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
     interface IAnimationCurveEditorComponentProps {
@@ -1008,6 +1028,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         playheadPos: number;
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
+        selectedCoordinate: number;
     }> {
         private _heightScale;
         readonly _entityName: string;
@@ -1015,37 +1036,38 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         private _svgKeyframes;
         private _isPlaying;
         private _graphCanvas;
-        private _selectedCurve;
         private _svgCanvas;
         private _isTargetedAnimation;
+        private _onBeforeRenderObserver;
+        private _mainAnimatable;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         /**
-        * Notifications
-        * To add notification we set the state and clear to make the notification bar hide.
-        */
+         * Notifications
+         * To add notification we set the state and clear to make the notification bar hide.
+         */
         clearNotification(): void;
         /**
-        * Zoom and Scroll
-        * This section handles zoom and scroll
-        * of the graph area.
-        */
+         * Zoom and Scroll
+         * This section handles zoom and scroll
+         * of the graph area.
+         */
         zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
         resetPlayheadOffset(): void;
         /**
-        * Keyframe Manipulation
-        * This section handles events from SvgDraggableArea.
-        */
+         * Keyframe Manipulation
+         * This section handles events from SvgDraggableArea.
+         */
         selectKeyframe(id: string): void;
         selectedControlPoint(type: string, id: string): void;
         updateValuePerCoordinate(dataType: number, value: number | Vector2 | Vector3 | Color3 | Color4 | Size | Quaternion, newValue: number, coordinate?: number): number | Vector3 | Quaternion | Color3 | Color4 | Vector2 | Size;
         renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, id: string): void;
         /**
-        * Actions
-        * This section handles events from GraphActionsBar.
-        */
+         * Actions
+         * This section handles events from GraphActionsBar.
+         */
         handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
         setFlatTangent(): void;
@@ -1056,9 +1078,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         /**
-        * Curve Rendering Functions
-        * This section handles how to render curves.
-        */
+         * Curve Rendering Functions
+         * This section handles how to render curves.
+         */
         linearInterpolation(keyframes: IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: Vector2, index: number): void;
         flatTangents(keyframes: IAnimationKey[], dataType: number): IAnimationKey[];
@@ -1083,20 +1105,23 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         setKeyframePoint(controlPoints: Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: Vector2, p1: Vector2, u: number, p2: Vector2, v: number, p3: Vector2): Vector2[] | undefined;
         /**
-        * Core functions
-        * This section handles main Curve Editor Functions.
-        */
+         * Core functions
+         * This section handles main Curve Editor Functions.
+         */
         selectAnimation(animation: Animation, coordinate?: SelectedCoordinate): void;
         isAnimationPlaying(): boolean;
         playStopAnimation(): boolean;
         analizeAnimationForLerp(animation: Animation | null): boolean;
         /**
-        * Timeline
-        * This section controls the timeline.
-        */
+         * Timeline
+         * This section controls the timeline.
+         */
         changeCurrentFrame(frame: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
+        moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
+        registerObs(): void;
+        componentWillUnmount(): void;
         render(): JSX.Element;
     }
 }
@@ -1126,9 +1151,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     }
 }
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animations/animationPropertyGridComponent" {
-    import * as React from "react";
-    import { Observable } from "babylonjs/Misc/observable";
-    import { Scene } from "babylonjs/scene";
+    import * as React from 'react';
+    import { Observable } from 'babylonjs/Misc/observable';
+    import { Scene } from 'babylonjs/scene';
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
     import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
     import { GlobalState } from "babylonjs-inspector/components/globalState";
@@ -3571,6 +3596,7 @@ declare module INSPECTOR {
         };
         blockMutationUpdates: boolean;
         selectedLineContainerTitles: Array<string>;
+        selectedLineContainerTitlesNoFocus: Array<string>;
         recorder: ReplayRecorder;
         private _onlyUseEulers;
         get onlyUseEulers(): boolean;
@@ -4166,7 +4192,10 @@ declare module INSPECTOR {
     }> {
         readonly _frames: object[];
         private _scrollable;
+        private _scrollbarHandle;
         private _direction;
+        private _scrolling;
+        private _shiftX;
         constructor(props: ITimelineProps);
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
@@ -4183,6 +4212,12 @@ declare module INSPECTOR {
         isFrameBeingUsed(frame: number, direction: number): number | false;
         dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
         dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+        scrollDragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDrag(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         render(): JSX.Element;
     }
 }
@@ -4190,9 +4225,19 @@ declare module INSPECTOR {
     interface IPlayheadProps {
         frame: number;
         offset: number;
+        onCurrentFrameChange: (frame: number) => void;
     }
     export class Playhead extends React.Component<IPlayheadProps> {
+        private _direction;
+        private _active;
         constructor(props: IPlayheadProps);
+        dragStart(e: React.TouchEvent<HTMLDivElement>): void;
+        dragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        drag(e: React.TouchEvent<HTMLDivElement>): void;
+        drag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        dragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+        dragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        calculateMove(): string;
         render(): JSX.Element;
     }
 }
@@ -4402,6 +4447,7 @@ declare module INSPECTOR {
         playheadPos: number;
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
+        selectedCoordinate: number;
     }> {
         private _heightScale;
         readonly _entityName: string;
@@ -4409,37 +4455,38 @@ declare module INSPECTOR {
         private _svgKeyframes;
         private _isPlaying;
         private _graphCanvas;
-        private _selectedCurve;
         private _svgCanvas;
         private _isTargetedAnimation;
+        private _onBeforeRenderObserver;
+        private _mainAnimatable;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         /**
-        * Notifications
-        * To add notification we set the state and clear to make the notification bar hide.
-        */
+         * Notifications
+         * To add notification we set the state and clear to make the notification bar hide.
+         */
         clearNotification(): void;
         /**
-        * Zoom and Scroll
-        * This section handles zoom and scroll
-        * of the graph area.
-        */
+         * Zoom and Scroll
+         * This section handles zoom and scroll
+         * of the graph area.
+         */
         zoom(e: React.WheelEvent<HTMLDivElement>): void;
         setAxesLength(): void;
         getValueLabel(i: number): number;
         resetPlayheadOffset(): void;
         /**
-        * Keyframe Manipulation
-        * This section handles events from SvgDraggableArea.
-        */
+         * Keyframe Manipulation
+         * This section handles events from SvgDraggableArea.
+         */
         selectKeyframe(id: string): void;
         selectedControlPoint(type: string, id: string): void;
         updateValuePerCoordinate(dataType: number, value: number | BABYLON.Vector2 | BABYLON.Vector3 | BABYLON.Color3 | BABYLON.Color4 | BABYLON.Size | BABYLON.Quaternion, newValue: number, coordinate?: number): number | BABYLON.Vector3 | BABYLON.Quaternion | BABYLON.Color3 | BABYLON.Color4 | BABYLON.Vector2 | BABYLON.Size;
         renderPoints(updatedSvgKeyFrame: IKeyframeSvgPoint, id: string): void;
         /**
-        * Actions
-        * This section handles events from GraphActionsBar.
-        */
+         * Actions
+         * This section handles events from GraphActionsBar.
+         */
         handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
         setFlatTangent(): void;
@@ -4450,9 +4497,9 @@ declare module INSPECTOR {
         removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         /**
-        * Curve Rendering Functions
-        * This section handles how to render curves.
-        */
+         * Curve Rendering Functions
+         * This section handles how to render curves.
+         */
         linearInterpolation(keyframes: BABYLON.IAnimationKey[], data: string, middle: number): string;
         setKeyframePointLinear(point: BABYLON.Vector2, index: number): void;
         flatTangents(keyframes: BABYLON.IAnimationKey[], dataType: number): BABYLON.IAnimationKey[];
@@ -4477,20 +4524,23 @@ declare module INSPECTOR {
         setKeyframePoint(controlPoints: BABYLON.Vector2[], index: number, keyframesCount: number): void;
         interpolateControlPoints(p0: BABYLON.Vector2, p1: BABYLON.Vector2, u: number, p2: BABYLON.Vector2, v: number, p3: BABYLON.Vector2): BABYLON.Vector2[] | undefined;
         /**
-        * Core functions
-        * This section handles main Curve Editor Functions.
-        */
+         * Core functions
+         * This section handles main Curve Editor Functions.
+         */
         selectAnimation(animation: BABYLON.Animation, coordinate?: SelectedCoordinate): void;
         isAnimationPlaying(): boolean;
         playStopAnimation(): boolean;
         analizeAnimationForLerp(animation: BABYLON.Animation | null): boolean;
         /**
-        * Timeline
-        * This section controls the timeline.
-        */
+         * Timeline
+         * This section controls the timeline.
+         */
         changeCurrentFrame(frame: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
+        moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
+        registerObs(): void;
+        componentWillUnmount(): void;
         render(): JSX.Element;
     }
 }

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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "cellPixelShader", function() { return cellPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -399,7 +399,7 @@ var cellPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cellVertexShader", function() { return cellVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -433,7 +433,7 @@ var cellVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CellMaterial", function() { return CellMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _cell_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cell.fragment */ "./cell/cell.fragment.ts");
 /* harmony import */ var _cell_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./cell.vertex */ "./cell/cell.vertex.ts");
@@ -773,14 +773,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -369,7 +369,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderSpecialParts", function() { return ShaderSpecialParts; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomMaterial", function() { return CustomMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -501,7 +501,7 @@ var CustomMaterial = /** @class */ (function (_super) {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 this._newSamplerInstances[kind + "-" + name] = param;
             }
             else {
@@ -627,7 +627,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderAlebdoParts", function() { return ShaderAlebdoParts; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRCustomMaterial", function() { return PBRCustomMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -758,7 +758,7 @@ var PBRCustomMaterial = /** @class */ (function (_super) {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 this._newSamplerInstances[kind + "-" + name] = param;
             }
             else {
@@ -890,14 +890,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "firePixelShader", function() { return firePixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -393,7 +393,7 @@ var firePixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fireVertexShader", function() { return fireVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -424,7 +424,7 @@ var fireVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FireMaterial", function() { return FireMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _fire_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fire.fragment */ "./fire/fire.fragment.ts");
 /* harmony import */ var _fire_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fire.vertex */ "./fire/fire.vertex.ts");
@@ -801,14 +801,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "furPixelShader", function() { return furPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -399,7 +399,7 @@ var furPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "furVertexShader", function() { return furVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -433,7 +433,7 @@ var furVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FurMaterial", function() { return FurMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _fur_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fur.fragment */ "./fur/fur.fragment.ts");
 /* harmony import */ var _fur_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fur.vertex */ "./fur/fur.vertex.ts");
@@ -963,14 +963,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "gradientPixelShader", function() { return gradientPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -399,7 +399,7 @@ var gradientPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gradientVertexShader", function() { return gradientVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -433,7 +433,7 @@ var gradientVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GradientMaterial", function() { return GradientMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _gradient_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gradient.fragment */ "./gradient/gradient.fragment.ts");
 /* harmony import */ var _gradient_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./gradient.vertex */ "./gradient/gradient.vertex.ts");
@@ -742,14 +742,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "gridPixelShader", function() { return gridPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -390,7 +390,7 @@ var gridPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gridVertexShader", function() { return gridVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -417,7 +417,7 @@ var gridVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GridMaterial", function() { return GridMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _grid_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./grid.fragment */ "./grid/grid.fragment.ts");
 /* harmony import */ var _grid_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./grid.vertex */ "./grid/grid.vertex.ts");
@@ -716,14 +716,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -383,7 +383,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lavaPixelShader", function() { return lavaPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -416,7 +416,7 @@ var lavaPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lavaVertexShader", function() { return lavaVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -450,7 +450,7 @@ var lavaVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LavaMaterial", function() { return LavaMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _lava_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lava.fragment */ "./lava/lava.fragment.ts");
 /* harmony import */ var _lava_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lava.vertex */ "./lava/lava.vertex.ts");
@@ -861,14 +861,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mixPixelShader", function() { return mixPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -445,7 +445,7 @@ var mixPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mixVertexShader", function() { return mixVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -479,7 +479,7 @@ var mixVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MixMaterial", function() { return MixMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _mix_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mix.fragment */ "./mix/mix.fragment.ts");
 /* harmony import */ var _mix_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mix.vertex */ "./mix/mix.vertex.ts");
@@ -966,14 +966,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalPixelShader", function() { return normalPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -445,7 +445,7 @@ var normalPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalVertexShader", function() { return normalVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -479,7 +479,7 @@ var normalVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NormalMaterial", function() { return NormalMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _normal_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./normal.fragment */ "./normal/normal.fragment.ts");
 /* harmony import */ var _normal_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./normal.vertex */ "./normal/normal.vertex.ts");
@@ -806,14 +806,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowOnlyPixelShader", function() { return shadowOnlyPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -444,7 +444,7 @@ var shadowOnlyPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowOnlyVertexShader", function() { return shadowOnlyVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -478,7 +478,7 @@ var shadowOnlyVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowOnlyMaterial", function() { return ShadowOnlyMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _shadowOnly_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shadowOnly.fragment */ "./shadowOnly/shadowOnly.fragment.ts");
 /* harmony import */ var _shadowOnly_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shadowOnly.vertex */ "./shadowOnly/shadowOnly.vertex.ts");
@@ -723,14 +723,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "simplePixelShader", function() { return simplePixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -445,7 +445,7 @@ var simplePixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "simpleVertexShader", function() { return simpleVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -479,7 +479,7 @@ var simpleVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleMaterial", function() { return SimpleMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _simple_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./simple.fragment */ "./simple/simple.fragment.ts");
 /* harmony import */ var _simple_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./simple.vertex */ "./simple/simple.vertex.ts");
@@ -764,14 +764,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skyPixelShader", function() { return skyPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -438,7 +438,7 @@ var skyPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skyVertexShader", function() { return skyVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -465,7 +465,7 @@ var skyVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkyMaterial", function() { return SkyMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _sky_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sky.fragment */ "./sky/sky.fragment.ts");
 /* harmony import */ var _sky_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sky.vertex */ "./sky/sky.vertex.ts");
@@ -796,14 +796,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "terrainPixelShader", function() { return terrainPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -445,7 +445,7 @@ var terrainPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "terrainVertexShader", function() { return terrainVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -479,7 +479,7 @@ var terrainVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TerrainMaterial", function() { return TerrainMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _terrain_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./terrain.fragment */ "./terrain/terrain.fragment.ts");
 /* harmony import */ var _terrain_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./terrain.vertex */ "./terrain/terrain.vertex.ts");
@@ -894,14 +894,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -413,7 +413,7 @@ __webpack_require__.r(__webpack_exports__);
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TriPlanarMaterial", function() { return TriPlanarMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _triplanar_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./triplanar.fragment */ "./triPlanar/triplanar.fragment.ts");
 /* harmony import */ var _triplanar_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./triplanar.vertex */ "./triPlanar/triplanar.vertex.ts");
@@ -818,7 +818,7 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "triplanarPixelShader", function() { return triplanarPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -851,7 +851,7 @@ var triplanarPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "triplanarVertexShader", function() { return triplanarVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -874,14 +874,14 @@ var triplanarVertexShader = { name: name, shader: shader };
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waterPixelShader", function() { return waterPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -448,7 +448,7 @@ var waterPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waterVertexShader", function() { return waterVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -484,7 +484,7 @@ var waterVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WaterMaterial", function() { return WaterMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _water_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./water.fragment */ "./water/water.fragment.ts");
 /* harmony import */ var _water_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./water.vertex */ "./water/water.vertex.ts");
@@ -1185,14 +1185,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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

@@ -7,7 +7,7 @@
 		exports["babylonjs-materials"] = factory(require("babylonjs"));
 	else
 		root["MATERIALS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__) {
 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__, "cellPixelShader", function() { return cellPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -399,7 +399,7 @@ var cellPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cellVertexShader", function() { return cellVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -433,7 +433,7 @@ var cellVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CellMaterial", function() { return CellMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _cell_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cell.fragment */ "./cell/cell.fragment.ts");
 /* harmony import */ var _cell_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./cell.vertex */ "./cell/cell.vertex.ts");
@@ -757,7 +757,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderSpecialParts", function() { return ShaderSpecialParts; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomMaterial", function() { return CustomMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -889,7 +889,7 @@ var CustomMaterial = /** @class */ (function (_super) {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 this._newSamplerInstances[kind + "-" + name] = param;
             }
             else {
@@ -1015,7 +1015,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderAlebdoParts", function() { return ShaderAlebdoParts; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRCustomMaterial", function() { return PBRCustomMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -1146,7 +1146,7 @@ var PBRCustomMaterial = /** @class */ (function (_super) {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 this._newSamplerInstances[kind + "-" + name] = param;
             }
             else {
@@ -1251,7 +1251,7 @@ babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registered
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "firePixelShader", function() { return firePixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -1278,7 +1278,7 @@ var firePixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fireVertexShader", function() { return fireVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -1309,7 +1309,7 @@ var fireVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FireMaterial", function() { return FireMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _fire_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fire.fragment */ "./fire/fire.fragment.ts");
 /* harmony import */ var _fire_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fire.vertex */ "./fire/fire.vertex.ts");
@@ -1667,7 +1667,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "furPixelShader", function() { return furPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -1700,7 +1700,7 @@ var furPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "furVertexShader", function() { return furVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -1734,7 +1734,7 @@ var furVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FurMaterial", function() { return FurMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _fur_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fur.fragment */ "./fur/fur.fragment.ts");
 /* harmony import */ var _fur_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fur.vertex */ "./fur/fur.vertex.ts");
@@ -2245,7 +2245,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gradientPixelShader", function() { return gradientPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -2278,7 +2278,7 @@ var gradientPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gradientVertexShader", function() { return gradientVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -2312,7 +2312,7 @@ var gradientVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GradientMaterial", function() { return GradientMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _gradient_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gradient.fragment */ "./gradient/gradient.fragment.ts");
 /* harmony import */ var _gradient_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./gradient.vertex */ "./gradient/gradient.vertex.ts");
@@ -2602,7 +2602,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gridPixelShader", function() { return gridPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -2626,7 +2626,7 @@ var gridPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gridVertexShader", function() { return gridVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -2653,7 +2653,7 @@ var gridVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GridMaterial", function() { return GridMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _grid_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./grid.fragment */ "./grid/grid.fragment.ts");
 /* harmony import */ var _grid_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./grid.vertex */ "./grid/grid.vertex.ts");
@@ -3031,7 +3031,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lavaPixelShader", function() { return lavaPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -3064,7 +3064,7 @@ var lavaPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lavaVertexShader", function() { return lavaVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -3098,7 +3098,7 @@ var lavaVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LavaMaterial", function() { return LavaMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _lava_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lava.fragment */ "./lava/lava.fragment.ts");
 /* harmony import */ var _lava_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lava.vertex */ "./lava/lava.vertex.ts");
@@ -3575,7 +3575,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mixPixelShader", function() { return mixPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -3608,7 +3608,7 @@ var mixPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mixVertexShader", function() { return mixVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -3642,7 +3642,7 @@ var mixVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MixMaterial", function() { return MixMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _mix_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mix.fragment */ "./mix/mix.fragment.ts");
 /* harmony import */ var _mix_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mix.vertex */ "./mix/mix.vertex.ts");
@@ -4156,7 +4156,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalPixelShader", function() { return normalPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4189,7 +4189,7 @@ var normalPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalVertexShader", function() { return normalVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4223,7 +4223,7 @@ var normalVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NormalMaterial", function() { return NormalMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _normal_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./normal.fragment */ "./normal/normal.fragment.ts");
 /* harmony import */ var _normal_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./normal.vertex */ "./normal/normal.vertex.ts");
@@ -4577,7 +4577,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowOnlyPixelShader", function() { return shadowOnlyPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4609,7 +4609,7 @@ var shadowOnlyPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowOnlyVertexShader", function() { return shadowOnlyVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4643,7 +4643,7 @@ var shadowOnlyVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowOnlyMaterial", function() { return ShadowOnlyMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _shadowOnly_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shadowOnly.fragment */ "./shadowOnly/shadowOnly.fragment.ts");
 /* harmony import */ var _shadowOnly_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shadowOnly.vertex */ "./shadowOnly/shadowOnly.vertex.ts");
@@ -4915,7 +4915,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "simplePixelShader", function() { return simplePixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4948,7 +4948,7 @@ var simplePixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "simpleVertexShader", function() { return simpleVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4982,7 +4982,7 @@ var simpleVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleMaterial", function() { return SimpleMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _simple_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./simple.fragment */ "./simple/simple.fragment.ts");
 /* harmony import */ var _simple_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./simple.vertex */ "./simple/simple.vertex.ts");
@@ -5294,7 +5294,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skyPixelShader", function() { return skyPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -5320,7 +5320,7 @@ var skyPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skyVertexShader", function() { return skyVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -5347,7 +5347,7 @@ var skyVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkyMaterial", function() { return SkyMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _sky_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sky.fragment */ "./sky/sky.fragment.ts");
 /* harmony import */ var _sky_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sky.vertex */ "./sky/sky.vertex.ts");
@@ -5705,7 +5705,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "terrainPixelShader", function() { return terrainPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -5738,7 +5738,7 @@ var terrainPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "terrainVertexShader", function() { return terrainVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -5772,7 +5772,7 @@ var terrainVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TerrainMaterial", function() { return TerrainMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _terrain_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./terrain.fragment */ "./terrain/terrain.fragment.ts");
 /* harmony import */ var _terrain_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./terrain.vertex */ "./terrain/terrain.vertex.ts");
@@ -6215,7 +6215,7 @@ __webpack_require__.r(__webpack_exports__);
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TriPlanarMaterial", function() { return TriPlanarMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _triplanar_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./triplanar.fragment */ "./triPlanar/triplanar.fragment.ts");
 /* harmony import */ var _triplanar_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./triplanar.vertex */ "./triPlanar/triplanar.vertex.ts");
@@ -6620,7 +6620,7 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "triplanarPixelShader", function() { return triplanarPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -6653,7 +6653,7 @@ var triplanarPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "triplanarVertexShader", function() { return triplanarVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -6703,7 +6703,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waterPixelShader", function() { return waterPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -6739,7 +6739,7 @@ var waterPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waterVertexShader", function() { return waterVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/effect");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -6775,7 +6775,7 @@ var waterVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WaterMaterial", function() { return WaterMaterial; });
 /* 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/decorators");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/effect");
 /* 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 _water_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./water.fragment */ "./water/water.fragment.ts");
 /* harmony import */ var _water_vertex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./water.vertex */ "./water/water.vertex.ts");
@@ -7476,14 +7476,14 @@ babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 
 /***/ }),
 
-/***/ "babylonjs/Misc/decorators":
+/***/ "babylonjs/Materials/effect":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_effect__;
 
 /***/ })
 

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


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


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

@@ -1 +1 @@
-{"thinEngineOnly":116131,"engineOnly":152567,"sceneOnly":514714,"minGridMaterial":651577,"minStandardMaterial":800106}
+{"thinEngineOnly":116133,"engineOnly":152569,"sceneOnly":514772,"minGridMaterial":651635,"minStandardMaterial":800164}

+ 24 - 1
dist/preview release/sandbox/babylon.sandbox.d.ts

@@ -74,9 +74,10 @@ declare module SANDBOX {
     interface IDropUpButtonProps {
         globalState: GlobalState;
         enabled: boolean;
-        icon: any;
+        icon?: any;
         label: string;
         options: string[];
+        selectedOption?: string;
         onOptionPicked: (option: string) => void;
     }
     export class DropUpButton extends React.Component<IDropUpButtonProps, {
@@ -104,6 +105,28 @@ declare module SANDBOX {
     }
 }
 declare module SANDBOX {
+    interface IAnimationBarProps {
+        globalState: GlobalState;
+        enabled: boolean;
+    }
+    export class AnimationBar extends React.Component<IAnimationBarProps, {
+        groupIndex: number;
+    }> {
+        private _currentScene;
+        private _sliderSyncObserver;
+        private _currentGroup;
+        private _sliderRef;
+        private _currentPlayingState;
+        constructor(props: IAnimationBarProps);
+        getCurrentPosition(): string;
+        registerBeforeRender(newScene: BABYLON.Scene): void;
+        pause(): void;
+        play(): void;
+        sliderInput(evt: React.FormEvent<HTMLInputElement>): void;
+        render(): JSX.Element | null;
+    }
+}
+declare module SANDBOX {
     interface IFooterProps {
         globalState: GlobalState;
     }

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


File diff suppressed because it is too large
+ 243 - 8
dist/preview release/sandbox/babylon.sandbox.max.js


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


+ 51 - 2
dist/preview release/sandbox/babylon.sandbox.module.d.ts

@@ -88,9 +88,10 @@ declare module "babylonjs-sandbox/components/dropUpButton" {
     interface IDropUpButtonProps {
         globalState: GlobalState;
         enabled: boolean;
-        icon: any;
+        icon?: any;
         label: string;
         options: string[];
+        selectedOption?: string;
         onOptionPicked: (option: string) => void;
     }
     export class DropUpButton extends React.Component<IDropUpButtonProps, {
@@ -119,6 +120,31 @@ declare module "babylonjs-sandbox/components/footerFileButton" {
         render(): JSX.Element | null;
     }
 }
+declare module "babylonjs-sandbox/components/animationBar" {
+    import * as React from "react";
+    import { GlobalState } from "babylonjs-sandbox/globalState";
+    import { Scene } from 'babylonjs/scene';
+    interface IAnimationBarProps {
+        globalState: GlobalState;
+        enabled: boolean;
+    }
+    export class AnimationBar extends React.Component<IAnimationBarProps, {
+        groupIndex: number;
+    }> {
+        private _currentScene;
+        private _sliderSyncObserver;
+        private _currentGroup;
+        private _sliderRef;
+        private _currentPlayingState;
+        constructor(props: IAnimationBarProps);
+        getCurrentPosition(): string;
+        registerBeforeRender(newScene: Scene): void;
+        pause(): void;
+        play(): void;
+        sliderInput(evt: React.FormEvent<HTMLInputElement>): void;
+        render(): JSX.Element | null;
+    }
+}
 declare module "babylonjs-sandbox/components/footer" {
     import * as React from "react";
     import { GlobalState } from "babylonjs-sandbox/globalState";
@@ -237,9 +263,10 @@ declare module SANDBOX {
     interface IDropUpButtonProps {
         globalState: GlobalState;
         enabled: boolean;
-        icon: any;
+        icon?: any;
         label: string;
         options: string[];
+        selectedOption?: string;
         onOptionPicked: (option: string) => void;
     }
     export class DropUpButton extends React.Component<IDropUpButtonProps, {
@@ -267,6 +294,28 @@ declare module SANDBOX {
     }
 }
 declare module SANDBOX {
+    interface IAnimationBarProps {
+        globalState: GlobalState;
+        enabled: boolean;
+    }
+    export class AnimationBar extends React.Component<IAnimationBarProps, {
+        groupIndex: number;
+    }> {
+        private _currentScene;
+        private _sliderSyncObserver;
+        private _currentGroup;
+        private _sliderRef;
+        private _currentPlayingState;
+        constructor(props: IAnimationBarProps);
+        getCurrentPosition(): string;
+        registerBeforeRender(newScene: BABYLON.Scene): void;
+        pause(): void;
+        play(): void;
+        sliderInput(evt: React.FormEvent<HTMLInputElement>): void;
+        render(): JSX.Element | null;
+    }
+}
+declare module SANDBOX {
     interface IFooterProps {
         globalState: GlobalState;
     }

+ 10 - 6
dist/preview release/viewer/babylon.module.d.ts

@@ -1069,9 +1069,10 @@ declare module "babylonjs/Materials/Textures/internalTextureLoader" {
         /**
          * This returns if the loader support the current file information.
          * @param extension defines the file extension of the file being loaded
+         * @param mimeType defines the optional mime type of the file being loaded
          * @returns true if the loader can load the specified file
          */
-        canLoad(extension: string): boolean;
+        canLoad(extension: string, mimeType?: string): boolean;
         /**
          * Uploads the cube texture data to the WebGL texture. It has already been bound.
          * @param data contains the texture data
@@ -56766,7 +56767,7 @@ declare module "babylonjs/Materials/PBR/pbrSheenConfiguration" {
         /**
          * Stores the sheen tint values in a texture.
          * rgb is tint
-         * a is a intensity
+         * a is a intensity or roughness if roughness has been defined
          */
         texture: Nullable<BaseTexture>;
         private _roughness;
@@ -58982,9 +58983,10 @@ declare module "babylonjs/Materials/Textures/Loaders/ktxTextureLoader" {
         /**
          * This returns if the loader support the current file information.
          * @param extension defines the file extension of the file being loaded
+         * @param mimeType defines the optional mime type of the file being loaded
          * @returns true if the loader can load the specified file
          */
-        canLoad(extension: string): boolean;
+        canLoad(extension: string, mimeType?: string): boolean;
         /**
          * Uploads the cube texture data to the WebGL texture. It has already been bound.
          * @param data contains the texture data
@@ -78913,9 +78915,10 @@ declare module BABYLON {
         /**
          * This returns if the loader support the current file information.
          * @param extension defines the file extension of the file being loaded
+         * @param mimeType defines the optional mime type of the file being loaded
          * @returns true if the loader can load the specified file
          */
-        canLoad(extension: string): boolean;
+        canLoad(extension: string, mimeType?: string): boolean;
         /**
          * Uploads the cube texture data to the WebGL texture. It has already been bound.
          * @param data contains the texture data
@@ -132265,7 +132268,7 @@ declare module BABYLON {
         /**
          * Stores the sheen tint values in a texture.
          * rgb is tint
-         * a is a intensity
+         * a is a intensity or roughness if roughness has been defined
          */
         texture: Nullable<BaseTexture>;
         private _roughness;
@@ -134348,9 +134351,10 @@ declare module BABYLON {
         /**
          * This returns if the loader support the current file information.
          * @param extension defines the file extension of the file being loaded
+         * @param mimeType defines the optional mime type of the file being loaded
          * @returns true if the loader can load the specified file
          */
-        canLoad(extension: string): boolean;
+        canLoad(extension: string, mimeType?: string): boolean;
         /**
          * Uploads the cube texture data to the WebGL texture. It has already been bound.
          * @param data contains the texture data

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


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


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

@@ -8,7 +8,7 @@
 - Added HDR texture filtering tools to the sandbox ([Sebavan](https://github.com/sebavan/))
 - Reflection probes can now be used to give accurate shading with PBR ([CraigFeldpsar](https://github.com/craigfeldspar) and ([Sebavan](https://github.com/sebavan/)))
 - Added editing of PBR materials, Post processes and Particle fragment shaders in the node material editor ([Popov72](https://github.com/Popov72))
-- Added Curve editor to manage entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
+- Added Curve editor to manage selected entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
 - Added support in `ShadowGenerator` for fast fake soft transparent shadows ([Popov72](https://github.com/Popov72))
 - Added support for **thin instances** for faster mesh instances. [Doc](https://doc.babylonjs.com/how_to/how_to_use_thininstances) ([Popov72](https://github.com/Popov72))
 
@@ -231,6 +231,7 @@
 - Fixed `DracoCompression` to not load empty data into attributes ([bghgary](https://github.com/bghgary))
 - Fixed `Mesh.subdivide` where one face could be lost depending on the number of subdivision ([Popov72](https://github.com/Popov72))
 - Fixed `AssetContainer.instantiateModelsToScene` with cloneMaterials=true and MultiMaterials to properly set the cloned submaterials ([ghempton](https://github.com/ghempton))
+- Fixed wrong display when setting `DefaultRenderingPipeline.imageProcessingEnabled` to `false` ([Popov72](https://github.com/Popov72))
 - Fix crash when loading a .obj file with vertex colors ([Popov72](https://github.com/Popov72))
 
 ## Breaking changes

+ 8 - 2
inspector/src/components/actionTabs/lineContainerComponent.tsx

@@ -26,11 +26,15 @@ export class LineContainerComponent extends React.Component<ILineContainerCompon
     }
 
     componentDidMount() {
-        if (this.props.globalState && this.props.globalState.selectedLineContainerTitles.length === 0) {
+        if (!this.props.globalState) {
             return;
         }
 
-        if (this.props.globalState && this.props.globalState.selectedLineContainerTitles.indexOf(this.props.title) > -1) {
+        if (this.props.globalState.selectedLineContainerTitles.length === 0 && this.props.globalState.selectedLineContainerTitlesNoFocus.length === 0) {
+            return;
+        }
+
+        if (this.props.globalState.selectedLineContainerTitles.indexOf(this.props.title) > -1) {
             setTimeout(() => {
                 this.props.globalState!.selectedLineContainerTitles = [];
             });
@@ -40,6 +44,8 @@ export class LineContainerComponent extends React.Component<ILineContainerCompon
             window.setTimeout(() => {
                 this.setState({ isHighlighted: false });
             }, 5000);
+        } else if (this.props.globalState.selectedLineContainerTitlesNoFocus.indexOf(this.props.title) > -1) {
+            this.setState({ isExpanded: true, isHighlighted: false });
         } else {
             this.setState({isExpanded: false});
         }

+ 21 - 15
inspector/src/components/actionTabs/lines/iconButtonLineComponent.tsx

@@ -1,21 +1,27 @@
-import * as React from "react";
+import * as React from 'react';
 
 export interface IIconButtonLineComponentProps {
-    icon: string;
-    onClick: () => void;
-    tooltip: string;
-    active?: boolean;
+  icon: string;
+  onClick: () => void;
+  tooltip: string;
+  active?: boolean;
 }
 
-export class IconButtonLineComponent extends React.Component<IIconButtonLineComponentProps> {
-    constructor(props: IIconButtonLineComponentProps) {
-        super(props);
-    }
+export class IconButtonLineComponent extends React.Component<
+  IIconButtonLineComponentProps
+> {
+  constructor(props: IIconButtonLineComponentProps) {
+    super(props);
+  }
 
-    render() {
-
-        return (
-            <div style={{backgroundColor: this.props.active ? '#111111' : 'transparent'}} title={this.props.tooltip} className={`icon ${this.props.icon}`} onClick={() => this.props.onClick()} />
-        );
-    }
+  render() {
+    return (
+      <div
+        style={{ backgroundColor: this.props.active ? '#111111' : '' }}
+        title={this.props.tooltip}
+        className={`icon ${this.props.icon}`}
+        onClick={() => this.props.onClick()}
+      />
+    );
+  }
 }

+ 346 - 253
inspector/src/components/actionTabs/tabs/propertyGrids/animations/addAnimation.tsx

@@ -1,8 +1,7 @@
-
-import * as React from "react";
+import * as React from 'react';
 import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
-import { Observable } from "babylonjs/Misc/observable";
-import { PropertyChangedEvent } from "../../../../../components/propertyChangedEvent";
+import { Observable } from 'babylonjs/Misc/observable';
+import { PropertyChangedEvent } from '../../../../../components/propertyChangedEvent';
 import { Animation } from 'babylonjs/Animations/animation';
 import { Vector2, Vector3, Quaternion } from 'babylonjs/Maths/math.vector';
 import { Size } from 'babylonjs/Maths/math.size';
@@ -10,277 +9,371 @@ import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
 
 interface IAddAnimationProps {
-   isOpen: boolean;
-   close: () => void;
-   entity: IAnimatable;
-   onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
-   setNotificationMessage: (message: string) => void;
-   changed: () => void;
+  isOpen: boolean;
+  close: () => void;
+  entity: IAnimatable;
+  onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+  setNotificationMessage: (message: string) => void;
+  changed: () => void;
 }
 
-export class AddAnimation extends React.Component<IAddAnimationProps, {animationName: string, animationTargetProperty: string, animationType:string, loopMode: number, animationTargetPath:string}>{ 
-    constructor(props: IAddAnimationProps) {
-        super(props);
-        this.state = { animationName: "", animationTargetPath: "", animationType: "Float", loopMode: Animation.ANIMATIONLOOPMODE_CYCLE, animationTargetProperty: ""}
-    }
-
-    getAnimationTypeofChange(selected: string) {
-        let dataType = 0;
-        switch (selected) {
-            case "Float":
-                dataType = Animation.ANIMATIONTYPE_FLOAT;
-                break;
-            case "Quaternion":
-                dataType = Animation.ANIMATIONTYPE_QUATERNION;
-                break;
-            case "Vector3":
-                dataType = Animation.ANIMATIONTYPE_VECTOR3;
-                break;
-            case "Vector2":
-                dataType = Animation.ANIMATIONTYPE_VECTOR2;
-                break;
-            case "Size":
-                dataType = Animation.ANIMATIONTYPE_SIZE;
-                break;
-            case "Color3":
-                dataType = Animation.ANIMATIONTYPE_COLOR3;
-                break;
-            case "Color4":
-                dataType = Animation.ANIMATIONTYPE_COLOR4;
-                break;
-        }
-
-        return dataType;
+export class AddAnimation extends React.Component<
+  IAddAnimationProps,
+  {
+    animationName: string;
+    animationTargetProperty: string;
+    animationType: string;
+    loopMode: number;
+    animationTargetPath: string;
+  }
+> {
+  constructor(props: IAddAnimationProps) {
+    super(props);
+    this.state = {
+      animationName: '',
+      animationTargetPath: '',
+      animationType: 'Float',
+      loopMode: Animation.ANIMATIONLOOPMODE_CYCLE,
+      animationTargetProperty: '',
+    };
+  }
 
+  getAnimationTypeofChange(selected: string) {
+    let dataType = 0;
+    switch (selected) {
+      case 'Float':
+        dataType = Animation.ANIMATIONTYPE_FLOAT;
+        break;
+      case 'Quaternion':
+        dataType = Animation.ANIMATIONTYPE_QUATERNION;
+        break;
+      case 'Vector3':
+        dataType = Animation.ANIMATIONTYPE_VECTOR3;
+        break;
+      case 'Vector2':
+        dataType = Animation.ANIMATIONTYPE_VECTOR2;
+        break;
+      case 'Size':
+        dataType = Animation.ANIMATIONTYPE_SIZE;
+        break;
+      case 'Color3':
+        dataType = Animation.ANIMATIONTYPE_COLOR3;
+        break;
+      case 'Color4':
+        dataType = Animation.ANIMATIONTYPE_COLOR4;
+        break;
     }
 
-    addAnimation() {
-        if (this.state.animationName != "" && this.state.animationTargetProperty != "") {
-
-            let matchTypeTargetProperty = this.state.animationTargetProperty.split('.');
-            let animationDataType = this.getAnimationTypeofChange(this.state.animationType);
-            let matched = false;
-
-            if (matchTypeTargetProperty.length === 1) {
-                let match = (this.props.entity as any)[matchTypeTargetProperty[0]];
+    return dataType;
+  }
 
-                if (match) {
-                    switch (match.constructor.name) {
-                        case "Vector2":
-                            animationDataType === Animation.ANIMATIONTYPE_VECTOR2 ? matched = true : matched = false;
-                            break;
-                        case "Vector3":
-                            animationDataType === Animation.ANIMATIONTYPE_VECTOR3 ? matched = true : matched = false;
-                            break;
-                        case "Quaternion":
-                            animationDataType === Animation.ANIMATIONTYPE_QUATERNION ? matched = true : matched = false;
-                            break;
-                        case "Color3":
-                            animationDataType === Animation.ANIMATIONTYPE_COLOR3 ? matched = true : matched = false;
-                            break;
-                        case "Color4":
-                            animationDataType === Animation.ANIMATIONTYPE_COLOR4 ? matched = true : matched = false;
-                            break;
-                        case "Size":
-                            animationDataType === Animation.ANIMATIONTYPE_SIZE ? matched = true : matched = false;
-                            break;
-                        default: console.log("not recognized");
-                            break;
-                    }
-                } else {
-                   this.props.setNotificationMessage(`The selected entity doesn't have a ${matchTypeTargetProperty[0]} property`)
-                }
-            } else if (matchTypeTargetProperty.length > 1) {
-                let match = (this.props.entity as any)[matchTypeTargetProperty[0]][matchTypeTargetProperty[1]];
-                if (typeof match === "number") {
-                    animationDataType === Animation.ANIMATIONTYPE_FLOAT ? matched = true : matched = false;
-                }
-            }
+  addAnimation() {
+    if (
+      this.state.animationName != '' &&
+      this.state.animationTargetProperty != ''
+    ) {
+      let matchTypeTargetProperty = this.state.animationTargetProperty.split(
+        '.'
+      );
+      let animationDataType = this.getAnimationTypeofChange(
+        this.state.animationType
+      );
+      let matched = false;
 
-            if (matched) {
+      if (matchTypeTargetProperty.length === 1) {
+        let match = (this.props.entity as any)[matchTypeTargetProperty[0]];
 
-                let startValue;
-                let endValue;
-                let outTangent;
-                let inTangent;
-                // Default start and end values for new animations
-                switch (animationDataType) {
-                    case Animation.ANIMATIONTYPE_FLOAT:
-                        startValue = 1;
-                        endValue = 1;
-                        outTangent = 0;
-                        inTangent = 0;
-                        break;
-                    case Animation.ANIMATIONTYPE_VECTOR2:
-                        startValue = new Vector2(1, 1);
-                        endValue = new Vector2(1, 1);
-                        outTangent = Vector2.Zero();
-                        inTangent = Vector2.Zero();
-                        break;
-                    case Animation.ANIMATIONTYPE_VECTOR3:
-                        startValue = new Vector3(1, 1, 1);
-                        endValue = new Vector3(1, 1, 1);
-                        outTangent = Vector3.Zero();
-                        inTangent = Vector3.Zero();
-                        break;
-                    case Animation.ANIMATIONTYPE_QUATERNION:
-                        startValue = new Quaternion(1, 1, 1, 1);
-                        endValue = new Quaternion(1, 1, 1, 1);
-                        outTangent = Quaternion.Zero();
-                        inTangent = Quaternion.Zero();
-                        break;
-                    case Animation.ANIMATIONTYPE_COLOR3:
-                        startValue = new Color3(1, 1, 1);
-                        endValue = new Color3(1, 1, 1);
-                        outTangent = new Color3(0, 0, 0);
-                        inTangent = new Color3(0, 0, 0);
-                        break;
-                    case Animation.ANIMATIONTYPE_COLOR4:
-                        startValue = new Color4(1, 1, 1, 1);
-                        endValue = new Color4(1, 1, 1, 1);
-                        outTangent = new Color4(0, 0, 0, 0);
-                        inTangent = new Color4(0, 0, 0, 0);
-                        break;
-                    case Animation.ANIMATIONTYPE_SIZE:
-                        startValue = new Size(1, 1);
-                        endValue = new Size(1, 1);
-                        outTangent = Size.Zero();
-                        inTangent = Size.Zero();
-                        break;
-                    default: console.log("not recognized");
-                        break;
-                }
+        if (match) {
+          switch (match.constructor.name) {
+            case 'Vector2':
+              animationDataType === Animation.ANIMATIONTYPE_VECTOR2
+                ? (matched = true)
+                : (matched = false);
+              break;
+            case 'Vector3':
+              animationDataType === Animation.ANIMATIONTYPE_VECTOR3
+                ? (matched = true)
+                : (matched = false);
+              break;
+            case 'Quaternion':
+              animationDataType === Animation.ANIMATIONTYPE_QUATERNION
+                ? (matched = true)
+                : (matched = false);
+              break;
+            case 'Color3':
+              animationDataType === Animation.ANIMATIONTYPE_COLOR3
+                ? (matched = true)
+                : (matched = false);
+              break;
+            case 'Color4':
+              animationDataType === Animation.ANIMATIONTYPE_COLOR4
+                ? (matched = true)
+                : (matched = false);
+              break;
+            case 'Size':
+              animationDataType === Animation.ANIMATIONTYPE_SIZE
+                ? (matched = true)
+                : (matched = false);
+              break;
+            default:
+              console.log('not recognized');
+              break;
+          }
+        } else {
+          this.props.setNotificationMessage(
+            `The selected entity doesn't have a ${matchTypeTargetProperty[0]} property`
+          );
+        }
+      } else if (matchTypeTargetProperty.length > 1) {
+        let matchProp = (this.props.entity as any)[matchTypeTargetProperty[0]];
+        if (matchProp) {
+          let match = matchProp[matchTypeTargetProperty[1]];
+          if (typeof match === 'number') {
+            animationDataType === Animation.ANIMATIONTYPE_FLOAT
+              ? (matched = true)
+              : (matched = false);
+          }
+        }
+      }
 
-                let alreadyAnimatedProperty = (this.props.entity as IAnimatable).animations?.find(anim =>
-                    anim.targetProperty === this.state.animationTargetProperty
-                    , this);
+      if (matched) {
+        let startValue;
+        let endValue;
+        let outTangent;
+        let inTangent;
+        // Default start and end values for new animations
+        switch (animationDataType) {
+          case Animation.ANIMATIONTYPE_FLOAT:
+            startValue = 1;
+            endValue = 1;
+            outTangent = 0;
+            inTangent = 0;
+            break;
+          case Animation.ANIMATIONTYPE_VECTOR2:
+            startValue = new Vector2(1, 1);
+            endValue = new Vector2(1, 1);
+            outTangent = Vector2.Zero();
+            inTangent = Vector2.Zero();
+            break;
+          case Animation.ANIMATIONTYPE_VECTOR3:
+            startValue = new Vector3(1, 1, 1);
+            endValue = new Vector3(1, 1, 1);
+            outTangent = Vector3.Zero();
+            inTangent = Vector3.Zero();
+            break;
+          case Animation.ANIMATIONTYPE_QUATERNION:
+            startValue = new Quaternion(1, 1, 1, 1);
+            endValue = new Quaternion(1, 1, 1, 1);
+            outTangent = Quaternion.Zero();
+            inTangent = Quaternion.Zero();
+            break;
+          case Animation.ANIMATIONTYPE_COLOR3:
+            startValue = new Color3(1, 1, 1);
+            endValue = new Color3(1, 1, 1);
+            outTangent = new Color3(0, 0, 0);
+            inTangent = new Color3(0, 0, 0);
+            break;
+          case Animation.ANIMATIONTYPE_COLOR4:
+            startValue = new Color4(1, 1, 1, 1);
+            endValue = new Color4(1, 1, 1, 1);
+            outTangent = new Color4(0, 0, 0, 0);
+            inTangent = new Color4(0, 0, 0, 0);
+            break;
+          case Animation.ANIMATIONTYPE_SIZE:
+            startValue = new Size(1, 1);
+            endValue = new Size(1, 1);
+            outTangent = Size.Zero();
+            inTangent = Size.Zero();
+            break;
+          default:
+            console.log('not recognized');
+            break;
+        }
 
-                let alreadyAnimationName = (this.props.entity as IAnimatable).animations?.find(anim =>
-                    anim.name === this.state.animationName
-                    , this);
+        let alreadyAnimatedProperty = (this.props
+          .entity as IAnimatable).animations?.find(
+          (anim) => anim.targetProperty === this.state.animationTargetProperty,
+          this
+        );
 
-                if (alreadyAnimatedProperty) {
-                    this.props.setNotificationMessage(`The property "${this.state.animationTargetProperty}" already has an animation`);
-                } else if (alreadyAnimationName) {
-                    this.props.setNotificationMessage(`There is already an animation with the name: "${this.state.animationName}"`);
-                } else {
+        let alreadyAnimationName = (this.props
+          .entity as IAnimatable).animations?.find(
+          (anim) => anim.name === this.state.animationName,
+          this
+        );
 
-                    let animation = new Animation(this.state.animationName, this.state.animationTargetProperty, 30, animationDataType);
+        if (alreadyAnimatedProperty) {
+          this.props.setNotificationMessage(
+            `The property "${this.state.animationTargetProperty}" already has an animation`
+          );
+        } else if (alreadyAnimationName) {
+          this.props.setNotificationMessage(
+            `There is already an animation with the name: "${this.state.animationName}"`
+          );
+        } else {
+          let animation = new Animation(
+            this.state.animationName,
+            this.state.animationTargetProperty,
+            30,
+            animationDataType
+          );
 
-                    // Start with two keyframes
-                    var keys = [];
-                    keys.push({
-                        frame: 0,
-                        value: startValue,
-                        outTangent: outTangent
-                    });
+          // Start with two keyframes
+          var keys = [];
+          keys.push({
+            frame: 0,
+            value: startValue,
+            outTangent: outTangent,
+          });
 
-                    keys.push({
-                        inTangent: inTangent,
-                        frame: 100,
-                        value: endValue
-                    });
+          keys.push({
+            inTangent: inTangent,
+            frame: 100,
+            value: endValue,
+          });
 
-                    animation.setKeys(keys);
+          animation.setKeys(keys);
 
-                    if (this.props.entity.animations){
-                        const store = this.props.entity.animations;
-                        const updatedCollection = [...this.props.entity.animations, animation]
-                        this.raiseOnPropertyChanged(updatedCollection, store);
-                        this.props.entity.animations = updatedCollection;
-                        this.props.changed();
-                        this.props.close();
-                        //Cleaning form fields
-                        this.setState({ animationName: "", animationTargetPath: "", animationType: "Float", loopMode: Animation.ANIMATIONLOOPMODE_CYCLE, animationTargetProperty: ""});
-                    }   
-                }
-            } else {
-                this.props.setNotificationMessage(`The property "${this.state.animationTargetProperty}" is not a "${this.state.animationType}" type`);
-            }
-        } else {
-            this.props.setNotificationMessage(`You need to provide a name and target property.`);
+          if (this.props.entity.animations) {
+            const store = this.props.entity.animations;
+            const updatedCollection = [
+              ...this.props.entity.animations,
+              animation,
+            ];
+            this.raiseOnPropertyChanged(updatedCollection, store);
+            this.props.entity.animations = updatedCollection;
+            this.props.changed();
+            this.props.close();
+            //Cleaning form fields
+            this.setState({
+              animationName: '',
+              animationTargetPath: '',
+              animationType: 'Float',
+              loopMode: Animation.ANIMATIONLOOPMODE_CYCLE,
+              animationTargetProperty: '',
+            });
+          }
         }
+      } else {
+        this.props.setNotificationMessage(
+          `The property "${this.state.animationTargetProperty}" is not a "${this.state.animationType}" type`
+        );
+      }
+    } else {
+      this.props.setNotificationMessage(
+        `You need to provide a name and target property.`
+      );
     }
+  }
 
-    raiseOnPropertyChanged(newValue: Animation[], previousValue: Animation[]) {
-        if (!this.props.onPropertyChangedObservable) {
-            return;
-        }
-
-        this.props.onPropertyChangedObservable.notifyObservers({
-            object: this.props.entity,
-            property: 'animations',
-            value: newValue,
-            initialValue: previousValue
-        });
+  raiseOnPropertyChanged(newValue: Animation[], previousValue: Animation[]) {
+    if (!this.props.onPropertyChangedObservable) {
+      return;
     }
 
-    handleNameChange(event: React.ChangeEvent<HTMLInputElement>) {
-        event.preventDefault();
-        this.setState({ animationName: event.target.value.trim() });
-    }
-    
-    handlePathChange(event: React.ChangeEvent<HTMLInputElement>) {
-        event.preventDefault();
-        this.setState({ animationTargetPath: event.target.value.trim() });
-    }
+    this.props.onPropertyChangedObservable.notifyObservers({
+      object: this.props.entity,
+      property: 'animations',
+      value: newValue,
+      initialValue: previousValue,
+    });
+  }
 
-    handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>) {
-        event.preventDefault();
-        this.setState({ animationType: event.target.value });
-    }
+  handleNameChange(event: React.ChangeEvent<HTMLInputElement>) {
+    event.preventDefault();
+    this.setState({ animationName: event.target.value.trim() });
+  }
 
-    handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>) {
-        event.preventDefault();
-        this.setState({ animationTargetProperty: event.target.value });
-    }
+  handlePathChange(event: React.ChangeEvent<HTMLInputElement>) {
+    event.preventDefault();
+    this.setState({ animationTargetPath: event.target.value.trim() });
+  }
 
-    handleLoopModeChange(event: React.ChangeEvent<HTMLSelectElement>) {
-        event.preventDefault();
-        this.setState({ loopMode: parseInt(event.target.value) });
-    }
-     
-    render() { 
-       return (
-        <div className="new-animation" style={{ display: this.props.isOpen ? "block" : "none" }}>
-            <div className="sub-content">
-            <div className="label-input">
-                <label>Target Path</label>
-                <input type="text" value={this.state.animationTargetPath} onChange={(e) => this.handlePathChange(e)}></input>
-            </div>
-            <div className="label-input">
-                <label>Display Name</label>
-                <input type="text" value={this.state.animationName} onChange={(e) => this.handleNameChange(e)}></input>
-            </div>
-            <div className="label-input">
-                <label>Property</label>
-                <input type="text" value={this.state.animationTargetProperty} onChange={(e) => this.handlePropertyChange(e)}></input>
-            </div>
-            <div className="label-input">
-                <label>Type</label>
-                <select onChange={(e) => this.handleTypeChange(e)} value={this.state.animationType}>
-                    <option value="Float">Float</option>
-                    <option value="Vector3">Vector3</option>
-                    <option value="Vector2">Vector2</option>
-                    <option value="Quaternion">Quaternion</option>
-                    <option value="Color3">Color3</option>
-                    <option value="Color4">Color4</option>
-                    <option value="Size">Size</option>
-                </select>
-            </div>
-            <div className="label-input">
-                <label>Loop Mode</label>
-                <select onChange={(e) => this.handleLoopModeChange(e)} value={this.state.loopMode}>
-                    <option value={Animation.ANIMATIONLOOPMODE_CYCLE}>Cycle</option>
-                    <option value={Animation.ANIMATIONLOOPMODE_RELATIVE}>Relative</option>
-                    <option value={Animation.ANIMATIONLOOPMODE_CONSTANT}>Constant</option>
-                </select>
-            </div>
-           <div className="confirm-buttons">
-            <ButtonLineComponent label={"Create"} onClick={() => this.addAnimation()} />
-            </div>
-            </div>
+  handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>) {
+    event.preventDefault();
+    this.setState({ animationType: event.target.value });
+  }
+
+  handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>) {
+    event.preventDefault();
+    this.setState({ animationTargetProperty: event.target.value });
+  }
+
+  handleLoopModeChange(event: React.ChangeEvent<HTMLSelectElement>) {
+    event.preventDefault();
+    this.setState({ loopMode: parseInt(event.target.value) });
+  }
+
+  render() {
+    return (
+      <div
+        className='new-animation'
+        style={{ display: this.props.isOpen ? 'block' : 'none' }}
+      >
+        <div className='sub-content'>
+          <div className='label-input'>
+            <label>Target Path</label>
+            <input
+              type='text'
+              value={this.state.animationTargetPath}
+              onChange={(e) => this.handlePathChange(e)}
+              disabled
+            ></input>
+          </div>
+          <div className='label-input'>
+            <label>Display Name</label>
+            <input
+              type='text'
+              value={this.state.animationName}
+              onChange={(e) => this.handleNameChange(e)}
+            ></input>
+          </div>
+          <div className='label-input'>
+            <label>Property</label>
+            <input
+              type='text'
+              value={this.state.animationTargetProperty}
+              onChange={(e) => this.handlePropertyChange(e)}
+            ></input>
+          </div>
+          <div className='label-input'>
+            <label>Type</label>
+            <select
+              onChange={(e) => this.handleTypeChange(e)}
+              value={this.state.animationType}
+            >
+              <option value='Float'>Float</option>
+              <option value='Vector3'>Vector3</option>
+              <option value='Vector2'>Vector2</option>
+              <option value='Quaternion'>Quaternion</option>
+              <option value='Color3'>Color3</option>
+              <option value='Color4'>Color4</option>
+              <option value='Size'>Size</option>
+            </select>
+          </div>
+          <div className='label-input'>
+            <label>Loop Mode</label>
+            <select
+              onChange={(e) => this.handleLoopModeChange(e)}
+              value={this.state.loopMode}
+            >
+              <option value={Animation.ANIMATIONLOOPMODE_CYCLE}>Cycle</option>
+              <option value={Animation.ANIMATIONLOOPMODE_RELATIVE}>
+                Relative
+              </option>
+              <option value={Animation.ANIMATIONLOOPMODE_CONSTANT}>
+                Constant
+              </option>
+            </select>
+          </div>
+          <div className='confirm-buttons'>
+            <ButtonLineComponent
+              label={'Create'}
+              onClick={() => this.addAnimation()}
+            />
+          </div>
         </div>
-        )
-    }
-} 
+      </div>
+    );
+  }
+}

File diff suppressed because it is too large
+ 1380 - 1033
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx


+ 300 - 209
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationPropertyGridComponent.tsx

@@ -1,13 +1,13 @@
-import * as React from "react";
+import * as React from 'react';
 
-import { Observable, Observer } from "babylonjs/Misc/observable";
-import { Scene } from "babylonjs/scene";
+import { Observable, Observer } from 'babylonjs/Misc/observable';
+import { Scene } from 'babylonjs/scene';
 
-import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
-import { ButtonLineComponent } from "../../../lines/buttonLineComponent";
-import { LineContainerComponent } from "../../../lineContainerComponent";
-import { SliderLineComponent } from "../../../lines/sliderLineComponent";
-import { LockObject } from "../lockObject";
+import { PropertyChangedEvent } from '../../../../propertyChangedEvent';
+import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
+import { LineContainerComponent } from '../../../lineContainerComponent';
+import { SliderLineComponent } from '../../../lines/sliderLineComponent';
+import { LockObject } from '../lockObject';
 import { GlobalState } from '../../../../globalState';
 import { Animation } from 'babylonjs/Animations/animation';
 import { Animatable } from 'babylonjs/Animations/animatable';
@@ -22,238 +22,329 @@ import { AnimationCurveEditorComponent } from '../animations/animationCurveEdito
 import { PopupComponent } from '../animations/popupComponent';
 
 interface IAnimationGridComponentProps {
-    globalState: GlobalState;
-    animatable: IAnimatable,
-    scene: Scene,
-    lockObject: LockObject,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+  globalState: GlobalState;
+  animatable: IAnimatable;
+  scene: Scene;
+  lockObject: LockObject;
+  onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
-export class AnimationGridComponent extends React.Component<IAnimationGridComponentProps, { currentFrame: number }> {
-    private _animations: Nullable<Animation[]> = null;
-    private _ranges: AnimationRange[];
-    private _mainAnimatable: Nullable<Animatable>;
-    private _onBeforeRenderObserver: Nullable<Observer<Scene>>;
-    private _isPlaying = false;
-    private timelineRef: React.RefObject<SliderLineComponent>;
-    private _isCurveEditorOpen = false;
-    private _animationControl = {
-        from: 0,
-        to: 0,
-        loop: false
-    }
-
-    constructor(props: IAnimationGridComponentProps) {
-        super(props);
-
-        this.state = { currentFrame: 0 };
-
-        const animatableAsAny = this.props.animatable as any;
+export class AnimationGridComponent extends React.Component<
+  IAnimationGridComponentProps,
+  { currentFrame: number }
+> {
+  private _animations: Nullable<Animation[]> = null;
+  private _ranges: AnimationRange[];
+  private _mainAnimatable: Nullable<Animatable>;
+  private _onBeforeRenderObserver: Nullable<Observer<Scene>>;
+  private _isPlaying = false;
+  private timelineRef: React.RefObject<SliderLineComponent>;
+  private _isCurveEditorOpen = false;
+  private _animationControl = {
+    from: 0,
+    to: 0,
+    loop: false,
+  };
 
-        this._ranges = animatableAsAny.getAnimationRanges ? animatableAsAny.getAnimationRanges() : [];
-        if (animatableAsAny.getAnimatables) {
-            const animatables = animatableAsAny.getAnimatables();
-            this._animations = new Array<Animation>();
+  constructor(props: IAnimationGridComponentProps) {
+    super(props);
 
-            animatables.forEach((animatable: IAnimatable) => {
-                if (animatable.animations) {
-                    this._animations!.push(...animatable.animations);
-                }
-            });
+    this.state = { currentFrame: 0 };
 
-            if (animatableAsAny.animations) {
-                this._animations!.push(...animatableAsAny.animations);
-            }
+    const animatableAsAny = this.props.animatable as any;
 
-            // Extract from and to
-            if (this._animations && this._animations.length) {
-                this._animations.forEach(animation => {
-                    let keys = animation.getKeys();
+    this._ranges = animatableAsAny.getAnimationRanges
+      ? animatableAsAny.getAnimationRanges()
+      : [];
+    if (animatableAsAny.getAnimatables) {
+      const animatables = animatableAsAny.getAnimatables();
+      this._animations = new Array<Animation>();
 
-                    if (keys && keys.length > 0) {
-                        if (keys[0].frame < this._animationControl.from) {
-                            this._animationControl.from = keys[0].frame;
-                        }
-                        const lastKeyIndex = keys.length - 1;
-                        if (keys[lastKeyIndex].frame > this._animationControl.to) {
-                            this._animationControl.to = keys[lastKeyIndex].frame;
-                        }
-                    }
-                });
-            }
+      animatables.forEach((animatable: IAnimatable) => {
+        if (animatable.animations) {
+          this._animations!.push(...animatable.animations);
         }
+      });
 
-        this.timelineRef = React.createRef();
-    }
+      if (animatableAsAny.animations) {
+        this._animations!.push(...animatableAsAny.animations);
+      }
 
-    playOrPause() {
-        const animatable = this.props.animatable;
-        this._isPlaying = this.props.scene.getAllAnimatablesByTarget(animatable).length > 0;
+      // Extract from and to
+      if (this._animations && this._animations.length) {
+        this._animations.forEach((animation) => {
+          let keys = animation.getKeys();
 
-        if (this._isPlaying) {
-            this.props.scene.stopAnimation(this.props.animatable);
-            this._mainAnimatable = null;
-        } else {
-            this._mainAnimatable = this.props.scene.beginAnimation(this.props.animatable, this._animationControl.from, this._animationControl.to, this._animationControl.loop);
-        }
-        this.forceUpdate();
-    }
-
-    componentDidMount() {
-        this._onBeforeRenderObserver = this.props.scene.onBeforeRenderObservable.add(() => {
-            if (!this._isPlaying || !this._mainAnimatable) {
-                return;
+          if (keys && keys.length > 0) {
+            if (keys[0].frame < this._animationControl.from) {
+              this._animationControl.from = keys[0].frame;
+            }
+            const lastKeyIndex = keys.length - 1;
+            if (keys[lastKeyIndex].frame > this._animationControl.to) {
+              this._animationControl.to = keys[lastKeyIndex].frame;
             }
-            this.setState({ currentFrame: this._mainAnimatable.masterFrame });
+          }
         });
+      }
     }
 
-    componentWillUnmount() {
-        if (this._onBeforeRenderObserver) {
-            this.props.scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
-            this._onBeforeRenderObserver = null;
-        }
-    }
+    this.timelineRef = React.createRef();
+  }
 
-    onCurrentFrameChange(value: number) {
-        if (!this._mainAnimatable) {
-            return;
-        }
+  playOrPause() {
+    const animatable = this.props.animatable;
+    this._isPlaying =
+      this.props.scene.getAllAnimatablesByTarget(animatable).length > 0;
 
-        this._mainAnimatable.goToFrame(value);
-        this.setState({ currentFrame: value });
+    if (this._isPlaying) {
+      this.props.scene.stopAnimation(this.props.animatable);
+      this._mainAnimatable = null;
+    } else {
+      this._mainAnimatable = this.props.scene.beginAnimation(
+        this.props.animatable,
+        this._animationControl.from,
+        this._animationControl.to,
+        this._animationControl.loop
+      );
     }
+    this.forceUpdate();
+  }
 
-    onChangeFromOrTo() {
-        this.playOrPause();
-        if (this._isPlaying) {
-            this.playOrPause();
+  componentDidMount() {
+    this._onBeforeRenderObserver = this.props.scene.onBeforeRenderObservable.add(
+      () => {
+        if (!this._isPlaying || !this._mainAnimatable) {
+          return;
         }
+        this.setState({ currentFrame: this._mainAnimatable.masterFrame });
+      }
+    );
+  }
+
+  componentWillUnmount() {
+    if (this._onBeforeRenderObserver) {
+      this.props.scene.onBeforeRenderObservable.remove(
+        this._onBeforeRenderObserver
+      );
+      this._onBeforeRenderObserver = null;
     }
+  }
 
-    onOpenAnimationCurveEditor() {
-        this._isCurveEditorOpen = true;
+  onCurrentFrameChange(value: number) {
+    if (!this._mainAnimatable) {
+      return;
     }
 
-    onCloseAnimationCurveEditor(window: Window | null) {
-        this._isCurveEditorOpen = false;
-        if (window === null) {
-            console.log("Window already closed");
-        } else {
-            window.close();
-        }
+    this._mainAnimatable.goToFrame(value);
+    this.setState({ currentFrame: value });
+  }
+
+  onChangeFromOrTo() {
+    this.playOrPause();
+    if (this._isPlaying) {
+      this.playOrPause();
     }
+  }
 
-    render() {
-        const animatable = this.props.animatable;
-        const animatableAsAny = this.props.animatable as any;
+  onOpenAnimationCurveEditor() {
+    this._isCurveEditorOpen = true;
+  }
 
-        let animatablesForTarget = this.props.scene.getAllAnimatablesByTarget(animatable);
-        this._isPlaying = animatablesForTarget.length > 0;
+  onCloseAnimationCurveEditor(window: Window | null) {
+    this._isCurveEditorOpen = false;
+    if (window === null) {
+      console.log('Window already closed');
+    } else {
+      window.close();
+    }
+  }
 
-        if (this._isPlaying && !this._mainAnimatable) {
-            this._mainAnimatable = animatablesForTarget[0];
-            if (this._mainAnimatable) {
-                this._animationControl.from = this._mainAnimatable.fromFrame;
-                this._animationControl.to = this._mainAnimatable.toFrame;
-                this._animationControl.loop = this._mainAnimatable.loopAnimation;
-            }
-        }
+  render() {
+    const animatable = this.props.animatable;
+    const animatableAsAny = this.props.animatable as any;
 
-        let animations = animatable.animations;
+    let animatablesForTarget = this.props.scene.getAllAnimatablesByTarget(
+      animatable
+    );
+    this._isPlaying = animatablesForTarget.length > 0;
 
-        return (
-            <div>
-                {
-                    this._ranges.length > 0 &&
-                    <LineContainerComponent globalState={this.props.globalState} title="ANIMATION RANGES">
-                        {
-                            this._ranges.map((range, i) => {
-                                return (
-                                    <ButtonLineComponent key={range.name + i} label={range.name}
-                                        onClick={() => {
-                                            this._mainAnimatable = null;
-                                            this.props.scene.beginAnimation(animatable, range.from, range.to, true)
-                                        }} />
-                                );
-                            })
-                        }
-                    </LineContainerComponent>
-                }
-                {
-                    animations &&
-                    <>
-                        <LineContainerComponent globalState={this.props.globalState} title="ANIMATIONS">
-                            <TextLineComponent label="Count" value={animations.length.toString()} />
-                            <ButtonLineComponent label="Edit" onClick={() => this.onOpenAnimationCurveEditor()} />
-                            {
-                                animations.map((anim, i) => {
-                                    return (
-                                        <TextLineComponent key={anim.targetProperty + i} label={"#" + i + " >"} value={anim.targetProperty} />
-                                    )
-                                })
-                            }
+    if (this._isPlaying && !this._mainAnimatable) {
+      this._mainAnimatable = animatablesForTarget[0];
+      if (this._mainAnimatable) {
+        this._animationControl.from = this._mainAnimatable.fromFrame;
+        this._animationControl.to = this._mainAnimatable.toFrame;
+        this._animationControl.loop = this._mainAnimatable.loopAnimation;
+      }
+    }
 
-                            {
+    let animations = animatable.animations;
 
-                                this._isCurveEditorOpen && <PopupComponent
-                                    id="curve-editor"
-                                    title="Curve Animation Editor"
-                                    size={{ width: 1024, height: 490 }}
-                                    onOpen={(window: Window) => { }}
-                                    onClose={(window: Window) => this.onCloseAnimationCurveEditor(window)}>
+    return (
+      <div>
+        {this._ranges.length > 0 && (
+          <LineContainerComponent
+            globalState={this.props.globalState}
+            title='ANIMATION RANGES'
+          >
+            {this._ranges.map((range, i) => {
+              return (
+                <ButtonLineComponent
+                  key={range.name + i}
+                  label={range.name}
+                  onClick={() => {
+                    this._mainAnimatable = null;
+                    this.props.scene.beginAnimation(
+                      animatable,
+                      range.from,
+                      range.to,
+                      true
+                    );
+                  }}
+                />
+              );
+            })}
+          </LineContainerComponent>
+        )}
+        {animations && (
+          <>
+            <LineContainerComponent
+              globalState={this.props.globalState}
+              title='ANIMATIONS'
+            >
+              <TextLineComponent
+                label='Count'
+                value={animations.length.toString()}
+              />
+              <ButtonLineComponent
+                label='Edit'
+                onClick={() => this.onOpenAnimationCurveEditor()}
+              />
+              {animations.map((anim, i) => {
+                return (
+                  <TextLineComponent
+                    key={anim.targetProperty + i}
+                    label={'#' + i + ' >'}
+                    value={anim.targetProperty}
+                  />
+                );
+              })}
 
-                                    <AnimationCurveEditorComponent
-                                        scene={this.props.scene}
-                                        entity={animatableAsAny}
-                                        close={(event) => this.onCloseAnimationCurveEditor(event.view)}
-                                        lockObject={this.props.lockObject}
-                                        playOrPause={() => this.playOrPause()} />
-                                </PopupComponent>
-                            }
-                        </LineContainerComponent>
-                        {
-                            animations.length > 0 &&
-                            <LineContainerComponent globalState={this.props.globalState} title="ANIMATION GENERAL CONTROL">
-                                <FloatLineComponent lockObject={this.props.lockObject} isInteger={true} label="From" target={this._animationControl} propertyName="from" onChange={() => this.onChangeFromOrTo()} />
-                                <FloatLineComponent lockObject={this.props.lockObject} isInteger={true} label="To" target={this._animationControl} propertyName="to" onChange={() => this.onChangeFromOrTo()} />
-                                <CheckBoxLineComponent label="Loop" onSelect={value => this._animationControl.loop = value} isSelected={() => this._animationControl.loop} />
-                                {
-                                    this._isPlaying &&
-                                    <SliderLineComponent ref={this.timelineRef} label="Current frame" minimum={this._animationControl.from} maximum={this._animationControl.to}
-                                        step={(this._animationControl.to - this._animationControl.from) / 1000.0} directValue={this.state.currentFrame}
-                                        onInput={value => this.onCurrentFrameChange(value)}
-                                    />
-                                }
-                                <ButtonLineComponent label={this._isPlaying ? "Stop" : "Play"} onClick={() => this.playOrPause()} />
-                                {
-                                    (this._ranges.length > 0 || this._animations && this._animations.length > 0) &&
-                                    <>
-                                        <CheckBoxLineComponent label="Enable override" onSelect={value => {
-                                            if (value) {
-                                                animatableAsAny.animationPropertiesOverride = new AnimationPropertiesOverride();
-                                                animatableAsAny.animationPropertiesOverride.blendingSpeed = 0.05;
-                                            } else {
-                                                animatableAsAny.animationPropertiesOverride = null;
-                                            }
-                                            this.forceUpdate();
-                                        }} isSelected={() => animatableAsAny.animationPropertiesOverride != null}
-                                            onValueChanged={() => this.forceUpdate()}
-                                        />
-                                        {
-                                            animatableAsAny.animationPropertiesOverride != null &&
-                                            <div>
-                                                <CheckBoxLineComponent label="Enable blending" target={animatableAsAny.animationPropertiesOverride} propertyName="enableBlending" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                                                <SliderLineComponent label="Blending speed" target={animatableAsAny.animationPropertiesOverride} propertyName="blendingSpeed" minimum={0} maximum={0.1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                                            </div>
-                                        }
-                                    </>
-                                }
-                            </LineContainerComponent>
+              {this._isCurveEditorOpen && (
+                <PopupComponent
+                  id='curve-editor'
+                  title='Curve Animation Editor'
+                  size={{ width: 1024, height: 490 }}
+                  onOpen={(window: Window) => {}}
+                  onClose={(window: Window) =>
+                    this.onCloseAnimationCurveEditor(window)
+                  }
+                >
+                  <AnimationCurveEditorComponent
+                    scene={this.props.scene}
+                    entity={animatableAsAny}
+                    close={(event) =>
+                      this.onCloseAnimationCurveEditor(event.view)
+                    }
+                    lockObject={this.props.lockObject}
+                    playOrPause={() => this.playOrPause()}
+                  />
+                </PopupComponent>
+              )}
+            </LineContainerComponent>
+            {animations.length > 0 && (
+              <LineContainerComponent
+                globalState={this.props.globalState}
+                title='ANIMATION GENERAL CONTROL'
+              >
+                <FloatLineComponent
+                  lockObject={this.props.lockObject}
+                  isInteger={true}
+                  label='From'
+                  target={this._animationControl}
+                  propertyName='from'
+                  onChange={() => this.onChangeFromOrTo()}
+                />
+                <FloatLineComponent
+                  lockObject={this.props.lockObject}
+                  isInteger={true}
+                  label='To'
+                  target={this._animationControl}
+                  propertyName='to'
+                  onChange={() => this.onChangeFromOrTo()}
+                />
+                <CheckBoxLineComponent
+                  label='Loop'
+                  onSelect={(value) => (this._animationControl.loop = value)}
+                  isSelected={() => this._animationControl.loop}
+                />
+                {this._isPlaying && (
+                  <SliderLineComponent
+                    ref={this.timelineRef}
+                    label='Current frame'
+                    minimum={this._animationControl.from}
+                    maximum={this._animationControl.to}
+                    step={
+                      (this._animationControl.to -
+                        this._animationControl.from) /
+                      1000.0
+                    }
+                    directValue={this.state.currentFrame}
+                    onInput={(value) => this.onCurrentFrameChange(value)}
+                  />
+                )}
+                <ButtonLineComponent
+                  label={this._isPlaying ? 'Stop' : 'Play'}
+                  onClick={() => this.playOrPause()}
+                />
+                {(this._ranges.length > 0 ||
+                  (this._animations && this._animations.length > 0)) && (
+                  <>
+                    <CheckBoxLineComponent
+                      label='Enable override'
+                      onSelect={(value) => {
+                        if (value) {
+                          animatableAsAny.animationPropertiesOverride = new AnimationPropertiesOverride();
+                          animatableAsAny.animationPropertiesOverride.blendingSpeed = 0.05;
+                        } else {
+                          animatableAsAny.animationPropertiesOverride = null;
                         }
-                    </>
-                }
-            </div>
-        );
-    }
-}
+                        this.forceUpdate();
+                      }}
+                      isSelected={() =>
+                        animatableAsAny.animationPropertiesOverride != null
+                      }
+                      onValueChanged={() => this.forceUpdate()}
+                    />
+                    {animatableAsAny.animationPropertiesOverride != null && (
+                      <div>
+                        <CheckBoxLineComponent
+                          label='Enable blending'
+                          target={animatableAsAny.animationPropertiesOverride}
+                          propertyName='enableBlending'
+                          onPropertyChangedObservable={
+                            this.props.onPropertyChangedObservable
+                          }
+                        />
+                        <SliderLineComponent
+                          label='Blending speed'
+                          target={animatableAsAny.animationPropertiesOverride}
+                          propertyName='blendingSpeed'
+                          minimum={0}
+                          maximum={0.1}
+                          step={0.01}
+                          onPropertyChangedObservable={
+                            this.props.onPropertyChangedObservable
+                          }
+                        />
+                      </div>
+                    )}
+                  </>
+                )}
+              </LineContainerComponent>
+            )}
+          </>
+        )}
+      </div>
+    );
+  }
+}

+ 132 - 55
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -1,3 +1,7 @@
+body {
+  background-color: rgb(51, 51, 51);
+}
+
 #animation-curve-editor {
   font-family: acumin-pro-condensed;
 
@@ -17,14 +21,14 @@
       height: 20px;
     }
     &.babylon-logo {
-      background-image: url("./assets/babylonLogo.svg");
+      background-image: url('./assets/babylonLogo.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
     }
 
     &.close {
-      background-image: url("./assets/closeWindowIcon.svg");
+      background-image: url('./assets/closeWindowIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -33,61 +37,103 @@
     }
 
     &.auto-tangent {
-      background-image: url("./assets/autoTangentIcon.svg");
+      background-image: url('./assets/autoTangentIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.break-tangent {
-      background-image: url("./assets/breakTangentIcon.svg");
+      background-image: url('./assets/breakTangentIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.flat-tangent {
-      background-image: url("./assets/flatTangentIcon.svg");
+      background-image: url('./assets/flatTangentIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.frame {
-      background-image: url("./assets/frameIcon.svg");
+      background-image: url('./assets/frameIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.linear-tangent {
-      background-image: url("./assets/linearTangentIcon.svg");
+      background-image: url('./assets/linearTangentIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.unify-tangent {
-      background-image: url("./assets/unifyTangentIcon.svg");
+      background-image: url('./assets/unifyTangentIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
       cursor: pointer;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.add-animation {
-      background-image: url("./assets/addAnimationIcon.svg");
+      background-image: url('./assets/addAnimationIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -96,7 +142,7 @@
     }
 
     &.animation-bullet {
-      background-image: url("./assets/animationBulletIcon.svg");
+      background-image: url('./assets/animationBulletIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -104,7 +150,7 @@
     }
 
     &.animation-delete {
-      background-image: url("./assets/animationDeleteIcon.svg");
+      background-image: url('./assets/animationDeleteIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -113,7 +159,7 @@
     }
 
     &.animation-edit {
-      background-image: url("./assets/editIcon.svg");
+      background-image: url('./assets/editIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -121,7 +167,7 @@
     }
 
     &.animation-end {
-      background-image: url("./assets/animationEndIcon.svg");
+      background-image: url('./assets/animationEndIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -132,7 +178,7 @@
     }
 
     &.animation-lastkey {
-      background-image: url("./assets/animationLastKeyIcon.svg");
+      background-image: url('./assets/animationLastKeyIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -140,12 +186,12 @@
       cursor: pointer;
       background-position: center;
       &:hover {
-        background-image: url("./assets/animationLastKeyHoverIcon.svg");
+        background-image: url('./assets/animationLastKeyHoverIcon.svg');
       }
     }
 
     &.animation-nextkey {
-      background-image: url("./assets/animationNextKeyIcon.svg");
+      background-image: url('./assets/animationNextKeyIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -153,12 +199,12 @@
       cursor: pointer;
       background-position: center;
       &:hover {
-        background-image: url("./assets/animationNextKeyHoverIcon.svg");
+        background-image: url('./assets/animationNextKeyHoverIcon.svg');
       }
     }
 
     &.animation-options {
-      background-image: url("./assets/animationOptionsIcon.svg");
+      background-image: url('./assets/animationOptionsIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -171,7 +217,7 @@
     }
 
     &.animation-playfwd {
-      background-image: url("./assets/animationPlayFwdIcon.svg");
+      background-image: url('./assets/animationPlayFwdIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -181,12 +227,12 @@
       cursor: pointer;
       background-position: center;
       &:hover {
-        background-image: url("./assets/animationPlayFwdHoverIcon.svg");
+        background-image: url('./assets/animationPlayFwdHoverIcon.svg');
       }
     }
 
     &.animation-playrev {
-      background-image: url("./assets/animationPlayRevIcon.svg");
+      background-image: url('./assets/animationPlayRevIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -196,12 +242,12 @@
       cursor: pointer;
       background-position: center;
       &:hover {
-        background-image: url("./assets/animationPlayRevHoverIcon.svg");
+        background-image: url('./assets/animationPlayRevHoverIcon.svg');
       }
     }
 
     &.animation-start {
-      background-image: url("./assets/animationStartIcon.svg");
+      background-image: url('./assets/animationStartIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -213,7 +259,7 @@
     }
 
     &.animation-stop {
-      background-image: url("./assets/animationStopIcon.svg");
+      background-image: url('./assets/animationStopIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -222,10 +268,11 @@
       cursor: pointer;
       background-position: center;
       width: 20px;
+      margin-left: 10px;
     }
 
     &.animation-triangle {
-      background-image: url("./assets/animationTriangleIcon.svg");
+      background-image: url('./assets/animationTriangleIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -233,7 +280,7 @@
     }
 
     &.key-active {
-      background-image: url("./assets/keyActiveIcon.svg");
+      background-image: url('./assets/keyActiveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -241,7 +288,7 @@
     }
 
     &.key-inactive {
-      background-image: url("./assets/keyInactiveIcon.svg");
+      background-image: url('./assets/keyInactiveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -249,7 +296,7 @@
     }
 
     &.key-selected {
-      background-image: url("./assets/keySelectedIcon.svg");
+      background-image: url('./assets/keySelectedIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -257,7 +304,7 @@
     }
 
     &.loop-active {
-      background-image: url("./assets/loopActiveIcon.svg");
+      background-image: url('./assets/loopActiveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -266,7 +313,7 @@
     }
 
     &.loop-inactive {
-      background-image: url("./assets/loopInactiveIcon.svg");
+      background-image: url('./assets/loopInactiveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -275,7 +322,7 @@
     }
 
     &.move {
-      background-image: url("./assets/moveIcon.svg");
+      background-image: url('./assets/moveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -283,7 +330,7 @@
     }
 
     &.save {
-      background-image: url("./assets/saveIcon.svg");
+      background-image: url('./assets/saveIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -292,7 +339,7 @@
     }
 
     &.load {
-      background-image: url("./assets/loadIcon.svg");
+      background-image: url('./assets/loadIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -301,7 +348,7 @@
     }
 
     &.checked {
-      background-image: url("./assets/checkboxCheckedIcon.svg");
+      background-image: url('./assets/checkboxCheckedIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -309,7 +356,7 @@
     }
 
     &.unchecked {
-      background-image: url("./assets/checkboxDefaultIcon.svg");
+      background-image: url('./assets/checkboxDefaultIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -317,15 +364,22 @@
     }
 
     &.new-key {
-      background-image: url("./assets/newKeyIcon.svg");
+      background-image: url('./assets/newKeyIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
       color: white;
+      &:hover {
+        background-color: #888888;
+      }
+
+      &:active {
+        background-color: #555555;
+      }
     }
 
     &.scale {
-      background-image: url("./assets/scaleIcon.svg");
+      background-image: url('./assets/scaleIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -333,7 +387,7 @@
     }
 
     &.scrollbar-handle {
-      background-image: url("./assets/scrollbarHandleIcon.svg");
+      background-image: url('./assets/scrollbarHandleIcon.svg');
       background-repeat: no-repeat;
       background-color: transparent;
       background-size: contain;
@@ -423,6 +477,7 @@
 
     .buttons-container {
       display: flex;
+      padding-left: 10px;
     }
 
     .action-input {
@@ -440,6 +495,9 @@
         border: none;
         background-color: black;
         padding: 6px;
+        &:focus {
+          outline: solid 1px #ccc;
+        }
       }
     }
   }
@@ -539,6 +597,12 @@
               height: 20px;
               background-color: #666666;
               justify-content: space-between;
+              position: absolute;
+
+              .scrollbar {
+                cursor: pointer;
+                width: 100%;
+              }
 
               .left-grabber,
               .right-grabber {
@@ -649,7 +713,7 @@
 
       .load-container {
         flex-direction: column;
-        height: 387px;
+        height: 377px;
         padding-top: 10px;
 
         .load-server {
@@ -658,7 +722,7 @@
           background-color: #222222;
           padding-left: 10px;
           height: 20px;
-          margin-top: 287px;
+          margin-top: 277px;
           p {
             margin: 0px;
           }
@@ -729,11 +793,11 @@
 
       .save-container {
         flex-direction: column;
-        height: 387px;
+        height: 377px;
         padding-top: 10px;
 
         .item-list {
-          height: 327px;
+          height: 317px;
           ul {
             list-style: none;
             padding-left: 10px;
@@ -830,7 +894,7 @@
         display: block;
         position: absolute;
         background-color: #111111;
-        height: 367px;
+        height: 377px;
         z-index: 10;
 
         .sub-header {
@@ -885,7 +949,7 @@
               height: auto;
             }
             &:before {
-              content: "";
+              content: '';
               background: none;
             }
             height: 20px;
@@ -906,7 +970,7 @@
             }
 
             .animation-bullet {
-              background-image: url("./assets/animationBulletIcon.svg");
+              background-image: url('./assets/animationBulletIcon.svg');
               background-repeat: no-repeat;
               background-color: transparent;
               background-size: contain;
@@ -920,7 +984,7 @@
 
             .animation-arrow {
               width: 30px;
-              background-image: url("./assets/animationTriangleIcon.svg");
+              background-image: url('./assets/animationTriangleIcon.svg');
               background-repeat: no-repeat;
               background-color: transparent;
               background-size: 10px;
@@ -942,7 +1006,7 @@
 
               &.show {
                 display: block;
-                background-image: url("./assets/keySelectedIcon.svg");
+                background-image: url('./assets/keySelectedIcon.svg');
                 background-repeat: no-repeat;
                 background-color: transparent;
                 background-size: 10px;
@@ -952,7 +1016,7 @@
               }
 
               &.hide {
-                display: none;
+                display: block;
               }
             }
 
@@ -986,8 +1050,7 @@
           font-size: 10px;
           &:focus {
             border-radius: 0px;
-            outline-style: auto;
-            outline-color: lightgrey;
+            outline: 1px solid #ccc;
           }
           font-family: acumin-pro-condensed;
         }
@@ -1001,8 +1064,7 @@
           color: white;
           &:focus {
             border-radius: 0px;
-            outline-style: auto;
-            outline-color: lightgrey;
+            outline: 1px solid #ccc;
           }
           font-family: acumin-pro-condensed;
         }
@@ -1045,7 +1107,7 @@
         }
         text {
           fill: #555555;
-          font-family: "acumin-pro-condensed";
+          font-family: 'acumin-pro-condensed';
         }
 
         .control-point {
@@ -1059,15 +1121,29 @@
         }
       }
 
-      .playhead-wrapper {
+      .playhead-container {
         position: relative;
+      }
+
+      .playhead-wrapper {
         left: -13px;
         bottom: 366px;
+        position: relative;
+      }
+
+      .playhead-scrollable {
+        width: 100px;
+        height: 33px;
+        position: absolute;
+        top: 335px;
+        left: -39px;
       }
 
       .playhead-handle {
         position: relative;
         top: 340px;
+        width: 22px;
+        height: 30px;
         .playhead {
           width: 22px;
           background-color: transparent;
@@ -1076,6 +1152,7 @@
           font-size: 12px;
           position: absolute;
           top: 1px;
+          cursor: pointer;
         }
 
         .playhead-circle {
@@ -1104,7 +1181,7 @@
     align-items: center;
     justify-items: stretch;
 
-    input[type="file"] {
+    input[type='file'] {
       display: none;
     }
 

+ 29 - 28
inspector/src/components/actionTabs/tabs/propertyGrids/animations/editorControls.tsx

@@ -1,17 +1,17 @@
-import * as React from "react";
+import * as React from 'react';
 
-import { Observable } from "babylonjs/Misc/observable";
-import { PropertyChangedEvent } from "../../../../../components/propertyChangedEvent";
-import { Animation } from "babylonjs/Animations/animation";
-import { IconButtonLineComponent } from "../../../lines/iconButtonLineComponent";
-import { NumericInputComponent } from "../../../lines/numericInputComponent";
-import { AddAnimation } from "./addAnimation";
-import { AnimationListTree, SelectedCoordinate } from "./animationListTree";
-import { IAnimatable } from "babylonjs/Animations/animatable.interface";
-import { TargetedAnimation } from "babylonjs/Animations/animationGroup";
-import { LoadSnippet } from "./loadsnippet";
-import { SaveSnippet } from "./saveSnippet";
-import { LockObject } from "../lockObject";
+import { Observable } from 'babylonjs/Misc/observable';
+import { PropertyChangedEvent } from '../../../../../components/propertyChangedEvent';
+import { Animation } from 'babylonjs/Animations/animation';
+import { IconButtonLineComponent } from '../../../lines/iconButtonLineComponent';
+import { NumericInputComponent } from '../../../lines/numericInputComponent';
+import { AddAnimation } from './addAnimation';
+import { AnimationListTree, SelectedCoordinate } from './animationListTree';
+import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
+import { TargetedAnimation } from 'babylonjs/Animations/animationGroup';
+import { LoadSnippet } from './loadsnippet';
+import { SaveSnippet } from './saveSnippet';
+import { LockObject } from '../lockObject';
 
 interface IEditorControlsProps {
   isTargetedAnimation: boolean;
@@ -52,6 +52,7 @@ export class EditorControls extends React.Component<
   }
 
   animationAdded() {
+    // select recently created animation/first coordinate...
     this.setState({
       animationsCount: this.recountAnimations(),
       isEditTabOpen: true,
@@ -123,40 +124,40 @@ export class EditorControls extends React.Component<
 
   render() {
     return (
-      <div className="animation-list">
-        <div className="controls-header">
+      <div className='animation-list'>
+        <div className='controls-header'>
           {this.props.isTargetedAnimation ? null : (
             <IconButtonLineComponent
               active={this.state.isAnimationTabOpen}
-              tooltip="Add Animation"
-              icon="medium add-animation"
+              tooltip='Add Animation'
+              icon='medium add-animation'
               onClick={() => this.handleTabs(0)}
             ></IconButtonLineComponent>
           )}
           <IconButtonLineComponent
             active={this.state.isLoadTabOpen}
-            tooltip="Load Animation"
-            icon="medium load"
+            tooltip='Load Animation'
+            icon='medium load'
             onClick={() => this.handleTabs(1)}
           ></IconButtonLineComponent>
           <IconButtonLineComponent
             active={this.state.isSaveTabOpen}
-            tooltip="Save Animation"
-            icon="medium save"
+            tooltip='Save Animation'
+            icon='medium save'
             onClick={() => this.handleTabs(2)}
           ></IconButtonLineComponent>
           {this.state.animationsCount === 0 ? null : (
             <IconButtonLineComponent
               active={this.state.isEditTabOpen}
-              tooltip="Edit Animations"
-              icon="medium animation-edit"
+              tooltip='Edit Animations'
+              icon='medium animation-edit'
               onClick={() => this.handleTabs(3)}
             ></IconButtonLineComponent>
           )}
           {this.state.isEditTabOpen ? (
-            <div className="input-fps">
+            <div className='input-fps'>
               <NumericInputComponent
-                label={""}
+                label={''}
                 precision={0}
                 value={this.state.framesPerSecond}
                 onChange={(framesPerSecond: number) =>
@@ -168,11 +169,11 @@ export class EditorControls extends React.Component<
           ) : null}
           {this.state.isEditTabOpen ? (
             <IconButtonLineComponent
-              tooltip="Loop/Unloop"
+              tooltip='Loop/Unloop'
               icon={`medium ${
                 this.state.isLoopActive
-                  ? "loop-active last"
-                  : "loop-inactive last"
+                  ? 'loop-active last'
+                  : 'loop-inactive last'
               }`}
               onClick={() => {
                 this.setState({ isLoopActive: !this.state.isLoopActive });

+ 85 - 47
inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx

@@ -1,52 +1,90 @@
-
-import * as React from "react";
+import * as React from 'react';
 import { IconButtonLineComponent } from '../../../lines/iconButtonLineComponent';
 
 interface IGraphActionsBarProps {
-   addKeyframe: () => void;
-   removeKeyframe: () => void;
-   handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
-   handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
-   flatTangent: () => void;
-   brokeTangents: () => void;
-   setLerpMode: () => void;
-   brokenMode: boolean;
-   lerpMode: boolean;
-   currentValue: number;
-   currentFrame: number;
-   title: string;
-   close: (event: any) => void;
-   enabled: boolean;
+  addKeyframe: () => void;
+  removeKeyframe: () => void;
+  handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+  handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+  flatTangent: () => void;
+  brokeTangents: () => void;
+  setLerpMode: () => void;
+  brokenMode: boolean;
+  lerpMode: boolean;
+  currentValue: number;
+  currentFrame: number;
+  title: string;
+  close: (event: any) => void;
+  enabled: boolean;
 }
 
-export class GraphActionsBar extends React.Component<IGraphActionsBarProps>{ 
-    constructor(props: IGraphActionsBarProps) {
-        super(props);
-    }
-     
-    render() { 
-       return (
-           <div className="actions-wrapper">
-               <div className="title-container">
-               <div className="icon babylon-logo"></div>
-               <div className="title">{this.props.title}</div>
-               </div>
-               <div className="buttons-container" style={{display: this.props.enabled ? 'flex' : 'none'}}>
-               <div className="action-input">
-               <input type="number" value={this.props.currentFrame} onChange={this.props.handleFrameChange} step="1"/>
-               </div>
-               <div className="action-input">
-               <input type="number" value={this.props.currentValue.toFixed(3)} onChange={this.props.handleValueChange} step="0.001"/>
-               </div>
-              <IconButtonLineComponent tooltip={"Add Keyframe"} icon="new-key" onClick={this.props.addKeyframe} />
-              <IconButtonLineComponent tooltip={"Remove Keyframe"} icon="frame" onClick={this.props.removeKeyframe} />
-              <IconButtonLineComponent tooltip={"Flat Tangents"} icon="flat-tangent" onClick={this.props.flatTangent} />
-              <IconButtonLineComponent tooltip={this.props.brokenMode ? "Broken Mode On" : "Broken Mode Off" } icon={this.props.brokenMode ? "break-tangent" : "unify-tangent" } onClick={this.props.brokeTangents} />
-              <IconButtonLineComponent tooltip={this.props.lerpMode ? "Lerp On" : "lerp Off" } icon="linear-tangent" onClick={this.props.setLerpMode} />
-              </div>
-              <div className="icon close" onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => this.props.close(event)}>
-              </div>
-           </div>
-        )
-    }
-} 
+export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
+  constructor(props: IGraphActionsBarProps) {
+    super(props);
+  }
+
+  render() {
+    return (
+      <div className='actions-wrapper'>
+        <div className='title-container'>
+          <div className='icon babylon-logo'></div>
+          <div className='title'>{this.props.title}</div>
+        </div>
+        <div
+          className='buttons-container'
+          style={{ display: this.props.enabled ? 'flex' : 'none' }}
+        >
+          <div className='action-input'>
+            <input
+              type='number'
+              value={this.props.currentFrame}
+              onChange={this.props.handleFrameChange}
+              step='1'
+            />
+          </div>
+          <div className='action-input'>
+            <input
+              type='number'
+              value={this.props.currentValue.toFixed(3)}
+              onChange={this.props.handleValueChange}
+              step='0.001'
+            />
+          </div>
+          <IconButtonLineComponent
+            tooltip={'Add Keyframe'}
+            icon='new-key'
+            onClick={this.props.addKeyframe}
+          />
+          <IconButtonLineComponent
+            tooltip={'Remove Keyframe'}
+            icon='frame'
+            onClick={this.props.removeKeyframe}
+          />
+          <IconButtonLineComponent
+            tooltip={'Flat Tangents'}
+            icon='flat-tangent'
+            onClick={this.props.flatTangent}
+          />
+          <IconButtonLineComponent
+            tooltip={
+              this.props.brokenMode ? 'Broken Mode On' : 'Broken Mode Off'
+            }
+            icon={this.props.brokenMode ? 'break-tangent' : 'unify-tangent'}
+            onClick={this.props.brokeTangents}
+          />
+          <IconButtonLineComponent
+            tooltip={this.props.lerpMode ? 'Lerp On' : 'lerp Off'}
+            icon='linear-tangent'
+            onClick={this.props.setLerpMode}
+          />
+        </div>
+        <div
+          className='icon close'
+          onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) =>
+            this.props.close(event)
+          }
+        ></div>
+      </div>
+    );
+  }
+}

+ 72 - 19
inspector/src/components/actionTabs/tabs/propertyGrids/animations/playhead.tsx

@@ -1,27 +1,80 @@
-
-import * as React from "react";
+import * as React from 'react';
 
 interface IPlayheadProps {
-    frame: number;
-    offset: number;
+  frame: number;
+  offset: number;
+  onCurrentFrameChange: (frame: number) => void;
 }
 
-export class Playhead extends React.Component<IPlayheadProps>{
-    constructor(props: IPlayheadProps) {
-        super(props);
-    }
+export class Playhead extends React.Component<IPlayheadProps> {
+  private _direction: number;
+  private _active: boolean;
+  constructor(props: IPlayheadProps) {
+    super(props);
+  }
+
+  dragStart(e: React.TouchEvent<HTMLDivElement>): void;
+  dragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  dragStart(e: any) {
+    e.preventDefault();
+    this._direction = e.clientX;
+    this._active = true;
+  }
+
+  drag(e: React.TouchEvent<HTMLDivElement>): void;
+  drag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  drag(e: any) {
+    e.preventDefault();
+    if (this._active) {
+      let moved = e.pageX - this._direction;
 
-    render() {
-        return (
-            <div className="playhead-wrapper" id="playhead" style={{ left: `calc(${this.props.frame * (this.props.offset)}px - 13px)` }}>
-                <div className="playhead-line"></div>
-                <div className="playhead-handle">
-                    <div className="playhead-circle"></div>
-                    <div className="playhead">{this.props.frame}</div>
-                </div>
-            </div>
-        )
+      let framesToMove = Math.round(Math.abs(moved) / 2);
+      console.log(framesToMove);
+      if (Math.sign(moved) === -1) {
+        this.props.onCurrentFrameChange(this.props.frame - 1);
+      } else {
+        this.props.onCurrentFrameChange(this.props.frame + 1);
+      }
     }
-}
+  }
+
+  dragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+  dragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  dragEnd(e: any) {
+    e.preventDefault();
+    this._direction = 0;
+    this._active = false;
+  }
 
+  calculateMove() {
+    return `calc(${this.props.frame * this.props.offset}px - 13px)`;
+  }
 
+  render() {
+    return (
+      <div
+        className='playhead-wrapper'
+        id='playhead'
+        style={{
+          left: this.calculateMove(),
+        }}
+      >
+        <div className='playhead-line'></div>
+        <div
+          className='playhead-handle'
+          onMouseMove={(e) => this.drag(e)}
+          onTouchMove={(e) => this.drag(e)}
+          onTouchStart={(e) => this.dragStart(e)}
+          onTouchEnd={(e) => this.dragEnd(e)}
+          onMouseDown={(e) => this.dragStart(e)}
+          onMouseUp={(e) => this.dragEnd(e)}
+          onMouseLeave={(e) => this.dragEnd(e)}
+          onDragStart={() => false}
+        >
+          <div className='playhead-circle'></div>
+          <div className='playhead'>{this.props.frame}</div>
+        </div>
+      </div>
+    );
+  }
+}

+ 290 - 184
inspector/src/components/actionTabs/tabs/propertyGrids/animations/timeline.tsx

@@ -1,215 +1,321 @@
-
-import * as React from "react";
+import * as React from 'react';
 import { IAnimationKey } from 'babylonjs/Animations/animationKey';
 import { Controls } from './controls';
 
 interface ITimelineProps {
-    keyframes: IAnimationKey[] | null;
-    selected: IAnimationKey | null;
-    currentFrame: number;
-    onCurrentFrameChange: (frame: number) => void;
-    dragKeyframe: (frame: number, index: number) => void;
-    playPause: (direction: number) => void;
-    isPlaying: boolean;
+  keyframes: IAnimationKey[] | null;
+  selected: IAnimationKey | null;
+  currentFrame: number;
+  onCurrentFrameChange: (frame: number) => void;
+  dragKeyframe: (frame: number, index: number) => void;
+  playPause: (direction: number) => void;
+  isPlaying: boolean;
 }
 
-export class Timeline extends React.Component<ITimelineProps, { selected: IAnimationKey, activeKeyframe: number | null }>{
-    readonly _frames: object[] = Array(300).fill({});
-    private _scrollable: React.RefObject<HTMLDivElement>;
-    private _direction: number;
-    constructor(props: ITimelineProps) {
-        super(props);
-        if (this.props.selected !== null) {
-            this.state = { selected: this.props.selected, activeKeyframe: null };
-        }
-        this._scrollable = React.createRef();
-        this._direction = 0;
+export class Timeline extends React.Component<
+  ITimelineProps,
+  { selected: IAnimationKey; activeKeyframe: number | null }
+> {
+  readonly _frames: object[] = Array(300).fill({});
+  private _scrollable: React.RefObject<HTMLDivElement>;
+  private _scrollbarHandle: React.RefObject<HTMLDivElement>;
+  private _direction: number;
+  private _scrolling: boolean;
+  private _shiftX: number;
+  constructor(props: ITimelineProps) {
+    super(props);
+    if (this.props.selected !== null) {
+      this.state = { selected: this.props.selected, activeKeyframe: null };
     }
+    this._scrollable = React.createRef();
+    this._scrollbarHandle = React.createRef();
+    this._direction = 0;
+    this._scrolling = false;
+    this._shiftX = 0;
+  }
 
-    playBackwards(event: React.MouseEvent<HTMLDivElement>) {
-        this.props.playPause(-1);
-    }
+  playBackwards(event: React.MouseEvent<HTMLDivElement>) {
+    this.props.playPause(-1);
+  }
 
-    play(event: React.MouseEvent<HTMLDivElement>) {
-        this.props.playPause(1);
-    }
+  play(event: React.MouseEvent<HTMLDivElement>) {
+    this.props.playPause(1);
+  }
 
-    pause(event: React.MouseEvent<HTMLDivElement>) {
-        if (this.props.isPlaying) {
-            this.props.playPause(1);
-        }
+  pause(event: React.MouseEvent<HTMLDivElement>) {
+    if (this.props.isPlaying) {
+      this.props.playPause(1);
     }
+  }
 
-    handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
-        this.props.onCurrentFrameChange(parseInt(event.target.value));
-        event.preventDefault();
+  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
+      );
     }
+  }
 
-    nextFrame(event: React.MouseEvent<HTMLDivElement>) {
-        event.preventDefault();
-        this.props.onCurrentFrameChange(this.props.currentFrame + 1);
-        (this._scrollable.current as HTMLDivElement).scrollLeft = this.props.currentFrame * 5;
+  nextKeyframe(event: React.MouseEvent<HTMLDivElement>) {
+    event.preventDefault();
+    if (this.props.keyframes !== null) {
+      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;
+      }
     }
+  }
 
-    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);
-        }
+  previousKeyframe(event: React.MouseEvent<HTMLDivElement>) {
+    event.preventDefault();
+    if (this.props.keyframes !== null) {
+      let keyframes = [...this.props.keyframes];
+      let first = keyframes
+        .reverse()
+        .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
+        );
+      }
     }
+  }
 
-    nextKeyframe(event: React.MouseEvent<HTMLDivElement>) {
-        event.preventDefault();
-        if (this.props.keyframes !== null) {
-            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;
-            }
+  dragStart(e: React.TouchEvent<SVGSVGElement>): void;
+  dragStart(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+  dragStart(e: any): void {
+    e.preventDefault();
+    this.setState({ activeKeyframe: parseInt(e.target.id.replace('kf_', '')) });
+    this._direction = e.clientX;
+  }
+
+  drag(e: React.TouchEvent<SVGSVGElement>): void;
+  drag(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+  drag(e: any): void {
+    e.preventDefault();
+    if (this.props.keyframes) {
+      if (
+        this.state.activeKeyframe === parseInt(e.target.id.replace('kf_', ''))
+      ) {
+        let updatedKeyframe = this.props.keyframes[this.state.activeKeyframe];
+        if (this._direction > e.clientX) {
+          console.log(`Dragging left ${this.state.activeKeyframe}`);
+          let used = this.isFrameBeingUsed(updatedKeyframe.frame - 1, -1);
+          if (used) {
+            updatedKeyframe.frame = used;
+          }
+        } else {
+          console.log(`Dragging Right ${this.state.activeKeyframe}`);
+          let used = this.isFrameBeingUsed(updatedKeyframe.frame + 1, 1);
+          if (used) {
+            updatedKeyframe.frame = used;
+          }
         }
+
+        this.props.dragKeyframe(
+          updatedKeyframe.frame,
+          this.state.activeKeyframe
+        );
+      }
     }
+  }
 
-    previousKeyframe(event: React.MouseEvent<HTMLDivElement>) {
-        event.preventDefault();
-        if (this.props.keyframes !== null) {
-            let keyframes = [...this.props.keyframes]
-            let first = keyframes.reverse().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);
-            }
-        }
+  isFrameBeingUsed(frame: number, direction: number) {
+    let used = this.props.keyframes?.find((kf) => kf.frame === frame);
+    if (used) {
+      this.isFrameBeingUsed(used.frame + direction, direction);
+      return false;
+    } else {
+      return frame;
     }
+  }
 
-    dragStart(e: React.TouchEvent<SVGSVGElement>): void;
-    dragStart(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
-    dragStart(e: any): void {
-        e.preventDefault();
-        this.setState({ activeKeyframe: parseInt(e.target.id.replace('kf_', '')) });
-        this._direction = e.clientX;
+  dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
+  dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
+  dragEnd(e: any): void {
+    e.preventDefault();
+    this._direction = 0;
+    this.setState({ activeKeyframe: null });
+  }
 
+  scrollDragStart(e: React.TouchEvent<HTMLDivElement>): void;
+  scrollDragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  scrollDragStart(e: any) {
+    e.preventDefault();
+    if ((e.target.class = 'scrollbar') && this._scrollbarHandle.current) {
+      this._scrolling = true;
+      this._shiftX =
+        e.clientX - this._scrollbarHandle.current.getBoundingClientRect().left;
+      this._scrollbarHandle.current.style.left = e.pageX - this._shiftX + 'px';
     }
+  }
 
-    drag(e: React.TouchEvent<SVGSVGElement>): void;
-    drag(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
-    drag(e: any): void {
-        e.preventDefault();
-        if (this.props.keyframes) {
-            if (this.state.activeKeyframe === parseInt(e.target.id.replace('kf_', ''))) {
-                let updatedKeyframe = this.props.keyframes[this.state.activeKeyframe];
-                if (this._direction > e.clientX) {
-                    console.log(`Dragging left ${this.state.activeKeyframe}`);
-                    let used = this.isFrameBeingUsed(updatedKeyframe.frame - 1, -1);
-                    if (used) {
-                        updatedKeyframe.frame = used
-                    }
-                } else {
-                    console.log(`Dragging Right ${this.state.activeKeyframe}`)
-                    let used = this.isFrameBeingUsed(updatedKeyframe.frame + 1, 1);
-                    if (used) {
-                        updatedKeyframe.frame = used
-                    }
-                }
-
-                this.props.dragKeyframe(updatedKeyframe.frame, this.state.activeKeyframe);
-
-            }
-        }
+  scrollDrag(e: React.TouchEvent<HTMLDivElement>): void;
+  scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  scrollDrag(e: any) {
+    e.preventDefault();
+    if (this._scrolling && this._scrollbarHandle.current) {
+      let moved = e.pageX - this._shiftX;
+      if (moved > 233 && moved < 630) {
+        this._scrollbarHandle.current.style.left = moved + 'px';
+        (this._scrollable.current as HTMLDivElement).scrollLeft = moved + 10;
+      }
     }
+  }
 
-    isFrameBeingUsed(frame: number, direction: number) {
-        let used = this.props.keyframes?.find(kf => kf.frame === frame);
-        if (used) {
-            this.isFrameBeingUsed(used.frame + direction, direction);
-            return false;
-        } else {
-            return frame;
-        }
-    }
+  scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
+  scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+  scrollDragEnd(e: any) {
+    e.preventDefault();
+    this._scrolling = false;
+    this._shiftX = 0;
+  }
 
-    dragEnd(e: React.TouchEvent<SVGSVGElement>): void;
-    dragEnd(e: React.MouseEvent<SVGSVGElement, MouseEvent>): void;
-    dragEnd(e: any): void {
-        e.preventDefault();
-        this._direction = 0;
-        this.setState({ activeKeyframe: null })
-    }
+  render() {
+    return (
+      <>
+        <div className='timeline'>
+          <Controls
+            keyframes={this.props.keyframes}
+            selected={this.props.selected}
+            currentFrame={this.props.currentFrame}
+            onCurrentFrameChange={this.props.onCurrentFrameChange}
+            playPause={this.props.playPause}
+            isPlaying={this.props.isPlaying}
+            scrollable={this._scrollable}
+          />
+          <div className='timeline-wrapper'>
+            <div ref={this._scrollable} className='display-line'>
+              <svg
+                viewBox='0 0 2010 40'
+                style={{ width: 2000, height: 40, backgroundColor: '#222222' }}
+                onMouseMove={(e) => this.drag(e)}
+                onTouchMove={(e) => this.drag(e)}
+                onTouchStart={(e) => this.dragStart(e)}
+                onTouchEnd={(e) => this.dragEnd(e)}
+                onMouseDown={(e) => this.dragStart(e)}
+                onMouseUp={(e) => this.dragEnd(e)}
+                onMouseLeave={(e) => this.dragEnd(e)}
+                onDragStart={() => false}
+              >
+                <line
+                  x1={this.props.currentFrame * 10}
+                  y1='0'
+                  x2={this.props.currentFrame * 10}
+                  y2='40'
+                  style={{ stroke: '#12506b', strokeWidth: 6 }}
+                />
+                {this.props.keyframes &&
+                  this.props.keyframes.map((kf, i) => {
+                    return (
+                      <svg
+                        key={`kf_${i}`}
+                        style={{ cursor: 'pointer' }}
+                        tabIndex={i + 40}
+                      >
+                        <line
+                          id={`kf_${i.toString()}`}
+                          x1={kf.frame * 10}
+                          y1='0'
+                          x2={kf.frame * 10}
+                          y2='40'
+                          style={{ stroke: 'red', strokeWidth: 6 }}
+                        />
+                      </svg>
+                    );
+                  })}
+                {this._frames.map((frame, i) => {
+                  return (
+                    <svg key={`tl_${i}`}>
+                      {i % 5 === 0 ? (
+                        <>
+                          <text
+                            x={i * 5 - 3}
+                            y='18'
+                            style={{ fontSize: 10, fill: '#555555' }}
+                          >
+                            {i}
+                          </text>
+                          <line
+                            x1={i * 5}
+                            y1='22'
+                            x2={i * 5}
+                            y2='40'
+                            style={{ stroke: '#555555', strokeWidth: 0.5 }}
+                          />
+                        </>
+                      ) : null}
+                    </svg>
+                  );
+                })}
+              </svg>
+            </div>
+
+            <div className='timeline-scroll-handle'>
+              <div className='scroll-handle'>
+                <div
+                  className='handle'
+                  ref={this._scrollbarHandle}
+                  style={{ width: 300 }}
+                >
+                  <div className='left-grabber'>
+                    <div className='grabber'></div>
+                    <div className='grabber'></div>
+                    <div className='grabber'></div>
+                    <div className='text'>20</div>
+                  </div>
+                  <div
+                    className='scrollbar'
+                    onMouseMove={(e) => this.scrollDrag(e)}
+                    onTouchMove={(e) => this.scrollDrag(e)}
+                    onTouchStart={(e) => this.scrollDragStart(e)}
+                    onTouchEnd={(e) => this.scrollDragEnd(e)}
+                    onMouseDown={(e) => this.scrollDragStart(e)}
+                    onMouseUp={(e) => this.scrollDragEnd(e)}
+                    onMouseLeave={(e) => this.scrollDragEnd(e)}
+                    onDragStart={() => false}
+                  ></div>
 
-    render() {
-        return (
-            <>
-                <div className="timeline">
-                    <Controls keyframes={this.props.keyframes}
-                        selected={this.props.selected}
-                        currentFrame={this.props.currentFrame}
-                        onCurrentFrameChange={this.props.onCurrentFrameChange}
-                        playPause={this.props.playPause}
-                        isPlaying={this.props.isPlaying}
-                        scrollable={this._scrollable} />
-                    <div className="timeline-wrapper">
-                        <div ref={this._scrollable} className="display-line" >
-                            <svg viewBox="0 0 2010 40" style={{ width: 2000, height: 40, backgroundColor: '#222222' }} onMouseMove={(e) => this.drag(e)}
-                                onTouchMove={(e) => this.drag(e)}
-                                onTouchStart={(e) => this.dragStart(e)}
-                                onTouchEnd={(e) => this.dragEnd(e)}
-                                onMouseDown={(e) => this.dragStart(e)}
-                                onMouseUp={(e) => this.dragEnd(e)}
-                                onMouseLeave={(e) => this.dragEnd(e)}>
-
-                                <line x1={this.props.currentFrame * 10} y1="0" x2={this.props.currentFrame * 10} y2="40" style={{ stroke: '#12506b', strokeWidth: 6 }} />
-                                {
-                                    this.props.keyframes && this.props.keyframes.map((kf, i) => {
-
-                                        return <svg key={`kf_${i}`} style={{ cursor: 'pointer' }} tabIndex={i + 40} >
-                                            <line id={`kf_${i.toString()}`} x1={kf.frame * 10} y1="0" x2={kf.frame * 10} y2="40" style={{ stroke: 'red', strokeWidth: 6 }} />
-                                        </svg>
-                                    })
-                                }
-                                {
-                                    this._frames.map((frame, i) => {
-
-                                        return <svg key={`tl_${i}`}>
-                                            {i % 5 === 0 ?
-                                                <>
-                                                    <text x={(i * 5) - 3} y="18" style={{ fontSize: 10, fill: '#555555' }}>{i}</text>
-                                                    <line x1={i * 5} y1="22" x2={i * 5} y2="40" style={{ stroke: '#555555', strokeWidth: 0.5 }} />
-                                                </> : null}
-
-                                        </svg>
-                                    })
-                                }
-                            </svg>
-                        </div>
-
-                        <div className="timeline-scroll-handle">
-                            <div className="scroll-handle">
-                                <div className="handle" style={{ width: 300, marginLeft: 20 }}>
-                                    <div className="left-grabber">
-                                        <div className="grabber"></div>
-                                        <div className="grabber"></div>
-                                        <div className="grabber"></div>
-                                        <div className="text">20</div>
-                                    </div>
-
-
-                                    <div className="right-grabber">
-                                        <div className="text">100</div>
-                                        <div className="grabber"></div>
-                                        <div className="grabber"></div>
-                                        <div className="grabber"></div>
-                                    </div>
-                                </div>
-                            </div>
-                            <div className="input-frame">
-                                <input type="number" value={this.props.currentFrame} onChange={(e) => this.handleInputChange(e)}></input>
-                            </div>
-                        </div>
-                    </div>
+                  <div className='right-grabber'>
+                    <div className='text'>100</div>
+                    <div className='grabber'></div>
+                    <div className='grabber'></div>
+                    <div className='grabber'></div>
+                  </div>
                 </div>
-            </>
-        )
-    }
-} 
+              </div>
+              <div className='input-frame'>
+                <input
+                  type='number'
+                  value={this.props.currentFrame}
+                  onChange={(e) => this.handleInputChange(e)}
+                ></input>
+              </div>
+            </div>
+          </div>
+        </div>
+      </>
+    );
+  }
+}

+ 3 - 3
inspector/src/components/globalState.ts

@@ -11,7 +11,6 @@ import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { ReplayRecorder } from './replayRecorder';
 import { DataStorage } from 'babylonjs/Misc/dataStorage';
 import { CodeChangedEvent } from './codeChangedEvent';
-import { Inspector } from '../inspector';
 
 export class GlobalState {
     public onSelectionChangedObservable: Observable<any>;
@@ -32,7 +31,8 @@ export class GlobalState {
     public glTFLoaderDefaults: { [key: string]: any } = { "validate": true };
 
     public blockMutationUpdates = false;
-    public selectedLineContainerTitles:Array<string> = [];
+    public selectedLineContainerTitles:Array<string> = [];    
+    public selectedLineContainerTitlesNoFocus:Array<string> = [];
 
     public recorder = new ReplayRecorder();
 
@@ -111,7 +111,7 @@ export class GlobalState {
             this.onValidationResultsUpdatedObservable.notifyObservers(results);
 
             if (results.issues.numErrors || results.issues.numWarnings) {
-                Inspector.MarkLineContainerTitleForHighlighting("GLTF VALIDATION");
+                this.selectedLineContainerTitlesNoFocus.push("GLTF VALIDATION");
                 this.onTabChangedObservable.notifyObservers(3);
             }
         });

+ 1 - 1
materialsLibrary/src/custom/customMaterial.ts

@@ -188,7 +188,7 @@ export class CustomMaterial extends StandardMaterial {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 (<any>this._newSamplerInstances)[kind + "-" + name] = param;
             }
             else {

+ 1 - 1
materialsLibrary/src/custom/pbrCustomMaterial.ts

@@ -190,7 +190,7 @@ export class PBRCustomMaterial extends PBRMaterial {
             this._newUniformInstances = {};
         }
         if (param) {
-            if (kind.indexOf("sampler") == -1) {
+            if (kind.indexOf("sampler") != -1) {
                 (<any>this._newSamplerInstances)[kind + "-" + name] = param;
             }
             else {

+ 2 - 0
sandbox/index.css

@@ -212,6 +212,8 @@ a:visited {
     background-color: var(--footer-background);    
     grid-column: 2;
     grid-row: 1;
+    padding: 0px;
+    margin: 0px;
 }
 
 .row {

+ 1 - 1
sandbox/public/index.html

@@ -16,13 +16,13 @@
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/libktx.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
     <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
     <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
 
     
+    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
     <script src="https://preview.babylonjs.com/sandbox/babylon.sandbox.js"></script>
     
     <style>

+ 162 - 0
sandbox/src/components/animationBar.tsx

@@ -0,0 +1,162 @@
+import * as React from "react";
+import { GlobalState } from '../globalState';
+import { DropUpButton } from './dropUpButton';
+import { Scene } from 'babylonjs/scene';
+import { Observer } from 'babylonjs/Misc/observable';
+import { Nullable } from 'babylonjs/types';
+import { AnimationGroup } from 'babylonjs/Animations/animationGroup';
+
+var iconPlay = require("../img/icon-play.svg");
+var iconPause = require("../img/icon-pause.svg");
+
+require("../scss/animationBar.scss");
+
+interface IAnimationBarProps {
+    globalState: GlobalState;
+    enabled: boolean;
+}
+
+export class AnimationBar extends React.Component<IAnimationBarProps, {groupIndex: number}> {
+    private _currentScene: Scene;
+    private _sliderSyncObserver: Nullable<Observer<Scene>>;
+    private _currentGroup: Nullable<AnimationGroup>;
+    private _sliderRef: React.RefObject<HTMLInputElement>;
+    private _currentPlayingState: boolean;
+
+    public constructor(props: IAnimationBarProps) {    
+        super(props);
+
+        this._sliderRef = React.createRef();
+
+        this.state = {groupIndex: 0};
+
+        props.globalState.onSceneLoaded.add(info => {
+            this.registerBeforeRender(info.scene);
+        });
+
+        if (this.props.globalState.currentScene) {
+            this.registerBeforeRender(this.props.globalState.currentScene); 
+        }
+    }
+
+    getCurrentPosition() {
+        if (!this._currentGroup) {
+            return "0";
+
+        }
+        let targetedAnimations = this._currentGroup.targetedAnimations;
+        if (targetedAnimations.length > 0) {
+            let runtimeAnimations = this._currentGroup.targetedAnimations[0].animation.runtimeAnimations;
+            if (runtimeAnimations.length > 0) {
+                return runtimeAnimations[0].currentFrame.toString();
+            }
+        }
+
+        return "0";
+    }
+
+    registerBeforeRender(newScene: Scene) {
+        if (this._currentScene) {
+            this._currentScene.onBeforeRenderObservable.remove(this._sliderSyncObserver);
+        }
+
+        this._currentScene = newScene;
+        this._sliderSyncObserver = this._currentScene.onBeforeRenderObservable.add(() => {
+            if (this._currentGroup && this._sliderRef.current) {
+                this._sliderRef.current.value = this.getCurrentPosition();
+
+                if (this._currentPlayingState !== this._currentGroup.isPlaying) {
+                    this.forceUpdate();
+                }
+            }
+        });
+    }
+
+    pause() {
+        if (!this._currentGroup) {
+            return;
+        }
+
+        this._currentGroup.pause();
+        this.forceUpdate();
+    }
+
+    play() {
+        if (!this._currentGroup) {
+            return;
+        }
+
+        this._currentGroup.play();
+        this.forceUpdate();
+    }
+
+    sliderInput(evt: React.FormEvent<HTMLInputElement>) {
+        if (!this._currentGroup) {
+            return;
+        }
+
+        let value = parseFloat((evt.target as HTMLInputElement).value);
+
+        if (!this._currentGroup.isPlaying) {
+            this._currentGroup.play(true);
+            this._currentGroup.goToFrame(value);
+            this._currentGroup.pause();
+        } else {
+            this._currentGroup.goToFrame(value);
+        }
+    }
+
+    public render() {
+        if (!this.props.enabled) {
+            this._currentGroup = null;
+            return null;
+        }
+        let scene = this.props.globalState.currentScene;
+        
+        if (scene.animationGroups.length === 0) {
+            this._currentGroup = null;
+            return null;
+        }
+        
+        let groupNames = scene.animationGroups.map(g => g.name);
+
+        this._currentGroup = scene.animationGroups[this.state.groupIndex];
+        this._currentPlayingState = this._currentGroup.isPlaying;
+
+        return (
+            <div className="animationBar">
+                <div className="row">
+                    <button id="playBtn">
+                        {
+                            this._currentGroup.isPlaying &&
+                            <img id="pauseImg" src={iconPause} onClick={() => this.pause()}/>
+                        }
+                        {
+                            !this._currentGroup.isPlaying &&
+                            <img id="playImg" src={iconPlay} onClick={() => this.play()}/>
+                        }
+                    </button>
+                    <input ref={this._sliderRef} className="slider" type="range" 
+                        onInput={evt => this.sliderInput(evt)}
+                        min={this._currentGroup.from} 
+                        max={this._currentGroup.to} 
+                        onChange={() => {}}
+                        value={this.getCurrentPosition()} step="any"></input>
+                </div>
+                <DropUpButton globalState={this.props.globalState} 
+                                    label="Active animation group"
+                                    options={groupNames}
+                                    selectedOption={this._currentGroup.name}
+                                    onOptionPicked={option => {
+                                        this._currentGroup!.stop();
+
+                                        let newIndex = groupNames.indexOf(option);
+                                        this.setState({groupIndex: newIndex});
+
+                                        scene.animationGroups[newIndex].play(true);
+                                    }}
+                                    enabled={true}/>
+            </div>            
+        )
+    }
+}

+ 30 - 8
sandbox/src/components/dropUpButton.tsx

@@ -3,13 +3,16 @@ import { GlobalState } from '../globalState';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
 
+var iconUp = require("../img/icon-up.svg");
+var iconDown = require("../img/icon-down.svg");
 
 interface IDropUpButtonProps {
     globalState: GlobalState;
     enabled: boolean;
-    icon: any;
+    icon?: any;
     label: string;
     options: string[];
+    selectedOption?: string;
     onOptionPicked: (option: string) => void;
 }
 
@@ -22,7 +25,7 @@ export class DropUpButton extends React.Component<IDropUpButtonProps, {isOpen: b
         this.state = {isOpen: false};
 
         this._onClickInterceptorClickedObserver = props.globalState.onClickInterceptorClicked.add(() => {
-            this.switchDropUp();
+            this.setState({isOpen: false});
         });
     }
 
@@ -46,13 +49,32 @@ export class DropUpButton extends React.Component<IDropUpButtonProps, {isOpen: b
         }
 
         return (
-            <>
-                <div className="button" onClick={() => this.switchDropUp()}>
-                    <img src={this.props.icon} alt={this.props.label} title={this.props.label}  />
-                </div>
+            <div className="dropup">
+                {
+                    this.props.icon &&
+                    <div className={"button" + (this.state.isOpen ? " active" : "")} onClick={() => this.switchDropUp()}>
+                        <img src={this.props.icon} alt={this.props.label} title={this.props.label}  />
+                    </div>
+                }
+                {
+                    this.props.selectedOption &&
+                    <div className={"button long" + (this.state.isOpen ? " active" : "")} onClick={() => this.switchDropUp()}> 
+                        {
+                            this.state.isOpen &&
+                            <img className="button-icon" src={iconDown} alt="Close the list" title="Close the list"  />
+                        }            
+                        {
+                            !this.state.isOpen &&
+                            <img className="button-icon" src={iconUp} alt="Open the list" title="Open the list"  />
+                        }           
+                        <div className="button-text" title={this.props.selectedOption}>
+                            {this.props.selectedOption}
+                        </div>                           
+                    </div>
+                }
                 {
                     this.state.isOpen &&
-                    <div className="dropup-content">
+                    <div className={"dropup-content" + (this.props.selectedOption ? " long-mode" : "")}>
                     {
                         this.props.options.map(o => {
                             return(
@@ -64,7 +86,7 @@ export class DropUpButton extends React.Component<IDropUpButtonProps, {isOpen: b
                     }
                     </div>
                 }
-            </>
+            </div>
         )
     }
 }

+ 4 - 2
sandbox/src/components/footer.tsx

@@ -4,6 +4,7 @@ import { FooterButton } from './footerButton';
 import { DropUpButton } from './dropUpButton';
 import { EnvironmentTools } from '../tools/environmentTools';
 import { FooterFileButton } from './footerFileButton';
+import { AnimationBar } from './animationBar';
 
 require("../scss/footer.scss");
 var babylonIdentity = require("../img/babylon-identity.svg");
@@ -16,8 +17,7 @@ interface IFooterProps {
 }
 
 export class Footer extends React.Component<IFooterProps> {
-    
-        
+            
     public constructor(props: IFooterProps) {    
         super(props);
         props.globalState.onSceneLoaded.add(info => {
@@ -42,6 +42,8 @@ export class Footer extends React.Component<IFooterProps> {
                 <div className="footerLeft">
                     <img id="logoImg" src={babylonIdentity}/>
                 </div>
+                <AnimationBar globalState={this.props.globalState} 
+                                enabled={!!this.props.globalState.currentScene}/>
                 <div className="footerRight">
                     <FooterFileButton globalState={this.props.globalState} 
                                 enabled={true}

+ 1 - 0
sandbox/src/img/icon-down.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 70"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:none;}</style></defs><title>DownArrowIcon</title><g id="Layer_2" data-name="Layer 2"><g id="Redlines"><path class="cls-1" d="M23.14,30.07l1.42-1.42L34.85,38.94,45.14,28.65l1.41,1.42L34.85,41.78Z"/><rect class="cls-2" width="70" height="70"/></g></g></svg>

+ 1 - 0
sandbox/src/img/icon-pause.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 70"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fff;}</style></defs><title>PauseIcon</title><g id="Layer_2" data-name="Layer 2"><g id="Redlines"><rect class="cls-1" width="70" height="70"/><path class="cls-2" d="M28.83,44.37v-20h2v20Zm10-20h2v20h-2Z"/></g></g></svg>

+ 1 - 0
sandbox/src/img/icon-play.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 70"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fff;}</style></defs><title>PlayIcon</title><g id="Layer_2" data-name="Layer 2"><g id="Redlines"><rect class="cls-1" width="70" height="70"/><path class="cls-2" d="M28.83,25.13l16,10-16,10Zm2,3.61V41.52l10.22-6.39Z"/></g></g></svg>

+ 1 - 0
sandbox/src/img/icon-up.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 70"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:none;}</style></defs><title>UpArrowIcon</title><g id="Layer_2" data-name="Layer 2"><g id="Redlines"><path class="cls-1" d="M34.85,29.78,24.56,40.06l-1.42-1.41L34.85,26.94l11.7,11.71-1.42,1.41Z"/><rect class="cls-2" width="70" height="70"/></g></g></svg>

+ 4 - 1
sandbox/src/sandbox.tsx

@@ -118,7 +118,10 @@ export class Sandbox extends React.Component<ISandboxProps, {isFooterVisible: bo
                     cameraPosition={this._cameraPosition} 
                     expanded={!this.state.isFooterVisible}/>                
                 <div ref={this._clickInterceptorRef} 
-                    onClick={() => this._globalState.onClickInterceptorClicked.notifyObservers()}
+                    onClick={() => {
+                        this._globalState.onClickInterceptorClicked.notifyObservers();
+                        this._clickInterceptorRef.current!.classList.add("hidden");
+                    }}
                     className="clickInterceptor hidden"></div>
                 {
                     this.state.isFooterVisible &&

+ 129 - 0
sandbox/src/scss/animationBar.scss

@@ -0,0 +1,129 @@
+.animationBar {
+    align-items: center;
+    color: white;
+    min-height: 30px;
+    height: var(--footer-height);
+    background-color: var(--footer-background);    
+    grid-column: 2;
+    grid-row: 1;
+    margin-left: 10px;
+    display: flex;
+
+    * {        
+        padding: 0px;
+        margin: 0px;
+    }
+
+    .row {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        flex-grow: 10;
+        align-items: center
+    }
+
+    #playBtn {    
+        display: flex;
+        align-items: center;
+        height: var(--footer-height);
+        width: var(--footer-height);
+        border: none;
+        background-color: inherit;
+        cursor: pointer;
+
+        img {
+            width: var(--footer-height);
+            height: var(--footer-height);
+        }
+
+        &:hover {
+            background-color: var(--button-hover-color);   
+        }
+    
+        &:active {
+            background-color: var(--button-hover-background);
+        }
+    
+        &:focus {
+            outline: none !important;
+            border: none;
+        }    
+    }
+
+    .slider {
+        -webkit-appearance: none;
+        cursor: pointer;
+        width: 100%;
+        max-width: 820px;
+        height: var(--footer-height);
+        outline: none;
+        margin-left: 20px;
+        margin-right: 10px;
+        background-color: transparent;
+    }
+
+    /*Chrome -webkit */
+    .slider::-webkit-slider-thumb {
+        -webkit-appearance: none;
+        width: 20px;
+        height: 20px;
+        border: 2px solid white;
+        border-radius: 50%;
+        background: var(--footer-background);
+        margin-top: -10px;
+    }
+    .slider::-webkit-slider-runnable-track {
+        height: 2px;
+        -webkit-appearance: none;
+        background-color: white;
+    }
+
+
+    /** FireFox -moz */
+    .slider::-moz-range-progress {
+    background-color: white;
+    height: 2px; 
+    }
+    .slider::-moz-range-thumb{
+        width: 20px;
+        height: 20px;
+        border: 2px solid white;
+        border-radius: 50%;
+        background: var(--footer-background);
+    }
+    .slider::-moz-range-track {
+        background: white;
+        height: 2px;
+    }
+
+    /** IE -ms */
+    .slider::-ms-track {
+        height: 2px;
+        
+        /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
+        background: transparent;
+        
+        /*leave room for the larger thumb to overflow with a transparent border */
+        border-color: transparent;
+        border-width: 10px 0;
+
+        /*remove default tick marks*/
+        color: transparent;
+    }
+    .slider::-ms-fill-lower {
+        background: white;
+        border-radius: 5px;
+    }
+    .slider::-ms-fill-upper {
+        background: white;
+        border-radius: 5px;
+    }
+    .slider::-ms-thumb {
+        width: 16px;
+        height: 16px;
+        border: 2px solid white;
+        border-radius: 50%;
+        background: var(--footer-background);
+        margin-top: 0px;
+    }
+}

+ 66 - 32
sandbox/src/scss/footer.scss

@@ -24,43 +24,70 @@
         }
     }
 
-    .footerRight {
-        display: flex;
-        flex-direction: row-reverse;
-        grid-column: 3;
-        grid-row: 1;
+    .button {
+        float: left; /* Float links side by side */
+        width: var(--footer-height);
+        height: var(--footer-height);
+        margin: 0px;
+        padding: 0;
+        transition: all 0.3s ease; /* Add transition for hover effects */
+        display: grid;
+        align-content: center;
+        justify-content: center;
+        cursor: pointer;
 
-        .button {
-            float: left; /* Float links side by side */
-            width: var(--footer-height);
-            height: var(--footer-height);
-            margin: 0px;
-            padding: 0;
-            transition: all 0.3s ease; /* Add transition for hover effects */
-            display: grid;
-            align-content: center;
-            justify-content: center;
-            cursor: pointer;
+        &.long {
+            width: 200px;
+            grid-template-columns: var(--footer-height) calc(200px - var(--footer-height));
 
-            img {
-                width: var(--footer-height);
-                height: var(--footer-height);
-            }
-            
-            &:hover {
-                background-color: var(--button-hover-color);
+            .button-icon {
+                grid-row: 1;
+                grid-column: 1;
             }
-            
-            &:active {
-                background-color: var(--button-hover-background);
+
+            .button-text {
+                grid-row: 1;
+                grid-column: 2;
+                align-self: center;
+                justify-self: left;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                font-size: var(--font-size)
             }
-        }         
+        }
+
+        &.active {
+            background-color: var(--button-hover-color);
+        }
+
+        img {
+            width: var(--footer-height);
+            height: var(--footer-height);
+        }
         
+        &:hover {
+            background-color: var(--button-hover-color);
+        }
+        
+        &:active {
+            background-color: var(--button-hover-background);
+        }
+    }   
+
+    .dropup {
+        position: relative;        
+
         .dropup-content {
             position: absolute;
             bottom: var(--footer-height);
-            right: 0px;     
-            z-index: 100;
+            left: 0px;     
+            z-index: 100;            
+            width: calc(2 * var(--footer-height));
+
+            &.long-mode {
+                width: 200px;
+            }
 
             div  {
                 background-color: var(--button-hover-color);
@@ -68,7 +95,7 @@
                 text-overflow: ellipsis;
                 white-space: nowrap;
                 font-size: var(--font-size);
-                width: calc(2 * var(--footer-height));
+                width: 100%;
                 color: white;
                 cursor: pointer;
                 height: 40px;
@@ -88,8 +115,15 @@
                     transition: all 0.3s ease;
                 }
             }
-        }    
-        
+        }     
+    }
+
+    .footerRight {
+        display: flex;
+        flex-direction: row-reverse;
+        grid-column: 3;
+        grid-row: 1;
+                     
         .custom-upload {
             position: relative;
             background-position: center right;

+ 1 - 1
sandbox/src/tools/environmentTools.ts

@@ -21,7 +21,7 @@ export class EnvironmentTools {
     ];    
 
     public static LoadSkyboxPathTexture(scene: Scene) {                
-        var defaultSkyboxIndex = LocalStorageHelper.ReadLocalStorageValue("defaultSkyboxId", 0);
+        var defaultSkyboxIndex = Math.max(0, LocalStorageHelper.ReadLocalStorageValue("defaultSkyboxId", 0));
         let path = this.SkyboxPath || this.Skyboxes[defaultSkyboxIndex];
         if (path.indexOf(".hdr") === (path.length - 4)) {
             return new HDRCubeTexture(path, scene, 256, false, true, false, true);

+ 6 - 2
src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts

@@ -334,9 +334,8 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen
         if (this._imageProcessingEnabled === enabled) {
             return;
         }
-        this._imageProcessingEnabled = enabled;
 
-        this._buildPipeline();
+        this._scene.imageProcessingConfiguration.isEnabled = enabled;
     }
 
     @serialize()
@@ -460,6 +459,11 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen
 
         this._imageProcessingConfigurationObserver = this._scene.imageProcessingConfiguration.onUpdateParameters.add(() => {
             this.bloom._downscale._exposure = this._scene.imageProcessingConfiguration.exposure;
+
+            if (this.imageProcessingEnabled !== this._scene.imageProcessingConfiguration.isEnabled) {
+                this._imageProcessingEnabled = this._scene.imageProcessingConfiguration.isEnabled;
+                this._buildPipeline();
+            }
         });
 
         this._buildPipeline();