Sfoglia il codice sorgente

fix dist merge conflicts

Trevor Baron 6 anni fa
parent
commit
44033871cf
55 ha cambiato i file con 53651 aggiunte e 23937 eliminazioni
  1. 334 287
      Playground/babylon.d.txt
  2. 4 1
      Playground/css/index.css
  3. 247 185
      dist/preview release/babylon.d.ts
  4. 2 2
      dist/preview release/babylon.js
  5. 261 88
      dist/preview release/babylon.max.js
  6. 1 1
      dist/preview release/babylon.max.js.map
  7. 507 383
      dist/preview release/babylon.module.d.ts
  8. 0 2
      dist/preview release/gui/babylon.gui.d.ts
  9. 4 70
      dist/preview release/gui/babylon.gui.js
  10. 1 1
      dist/preview release/gui/babylon.gui.js.map
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js
  12. 0 4
      dist/preview release/gui/babylon.gui.module.d.ts
  13. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 98 6
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  15. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  16. 13 11
      dist/preview release/inspector/babylon.inspector.d.ts
  17. 28 23
      dist/preview release/inspector/babylon.inspector.module.d.ts
  18. 319 1
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  19. 15 5
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  20. 24877 123
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  21. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  22. 691 2
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  23. 1 1
      dist/preview release/packagesSizeBaseLine.json
  24. 25357 22263
      dist/preview release/viewer/babylon.module.d.ts
  25. 466 326
      dist/preview release/viewer/babylon.viewer.js
  26. 4 4
      dist/preview release/viewer/babylon.viewer.max.js
  27. 11 1
      dist/preview release/what's new.md
  28. 1 1
      gui/src/2D/advancedDynamicTexture.ts
  29. 3 71
      gui/src/2D/controls/colorpicker.ts
  30. 99 5
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonShadowLightPropertyGridComponent.tsx
  31. 16 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx
  32. 1 0
      inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx
  33. 13 0
      inspector/src/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent.tsx
  34. 1 1
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  35. 3 1
      sandbox/index-local.html
  36. 10 2
      sandbox/index.css
  37. 3 1
      sandbox/index.html
  38. 12 4
      src/Actions/action.ts
  39. 5 1
      src/Animations/animatable.ts
  40. 22 19
      src/Behaviors/Meshes/pointerDragBehavior.ts
  41. 2 1
      src/Gamepads/Controllers/gearVRController.ts
  42. 3 2
      src/Gamepads/gamepadManager.ts
  43. 57 0
      src/Lights/Shadows/shadowGenerator.ts
  44. 4 6
      src/Loading/loadingScreen.ts
  45. 1 1
      src/Materials/PBR/pbrBaseMaterial.ts
  46. 1 1
      src/Materials/PBR/pbrMaterial.ts
  47. 0 2
      src/Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts
  48. 99 0
      src/Maths/math.ts
  49. 14 6
      src/Meshes/Builders/cylinderBuilder.ts
  50. 10 5
      src/Meshes/linesMesh.ts
  51. 7 3
      src/Meshes/mesh.ts
  52. 2 1
      src/Meshes/meshBuilder.ts
  53. 7 0
      src/Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts
  54. 4 3
      src/Rendering/renderingGroup.ts
  55. 1 1
      src/assetContainer.ts

+ 334 - 287
Playground/babylon.d.txt

@@ -460,6 +460,16 @@ declare module BABYLON {
          */
         toLinearSpace(): Color3;
         /**
+         * Converts current color in rgb space to HSV values
+         * @returns a new color3 representing the HSV values
+         */
+        toHSV(): Color3;
+        /**
+         * Converts current color in rgb space to HSV values
+         * @param result defines the Color3 where to store the HSV values
+         */
+        toHSVToRef(result: Color3): void;
+        /**
          * Converts the Color3 values to linear space and stores the result in "convertedColor"
          * @param convertedColor defines the Color3 object where to store the linear space version
          * @returns the unmodified Color3
@@ -478,6 +488,14 @@ declare module BABYLON {
         toGammaSpaceToRef(convertedColor: Color3): Color3;
         private static _BlackReadOnly;
         /**
+         * Convert Hue, saturation and value to a Color3 (RGB)
+         * @param hue defines the hue
+         * @param saturation defines the saturation
+         * @param value defines the value
+         * @param result defines the Color3 where to store the RGB values
+         */
+        static HSVtoRGBToRef(hue: number, saturation: number, value: number, result: Color3): void;
+        /**
          * Creates a new Color3 from the string containing valid hexadecimal values
          * @param hex defines a string containing valid hexadecimal values
          * @returns a new Color3 object
@@ -1217,6 +1235,7 @@ declare module BABYLON {
          */
         z: number;
         private static _UpReadOnly;
+        private static _ZeroReadOnly;
         /**
          * Creates a new Vector3 object from the given x, y, z (floats) coordinates.
          * @param x defines the first coordinates (on X axis)
@@ -1641,6 +1660,10 @@ declare module BABYLON {
          */
         static readonly UpReadOnly: DeepImmutable<Vector3>;
         /**
+         * Gets a zero Vector3 that must not be updated
+         */
+        static readonly ZeroReadOnly: DeepImmutable<Vector3>;
+        /**
          * Returns a new Vector3 set to (0.0, -1.0, 0.0)
          * @returns a new down Vector3
          */
@@ -5135,20 +5158,6 @@ declare module BABYLON {
         /** @hidden */
         protected _keys: string[];
         private _isDirty;
-<<<<<<< HEAD
-        /** @hidden */
renderId: number;
-        /** @hidden */
areLightsDirty: boolean;
-        /** @hidden */
areAttributesDirty: boolean;
-        /** @hidden */
areTexturesDirty: boolean;
-        /** @hidden */
areFresnelDirty: boolean;
-        /** @hidden */
areMiscDirty: boolean;
-        /** @hidden */
areImageProcessingDirty: boolean;
-        /** @hidden */
normals: boolean;
-        /** @hidden */
uvs: boolean;
-        /** @hidden */
needNormals: boolean;
-        /** @hidden */
needUVs: boolean;
-        [id: string]: any;
-=======
         /** @hidden */
private _renderId: number;
         /** @hidden */
private _areLightsDirty: boolean;
         /** @hidden */
private _areAttributesDirty: boolean;
@@ -5160,7 +5169,7 @@ declare module BABYLON {
         /** @hidden */
private _uvs: boolean;
         /** @hidden */
private _needNormals: boolean;
         /** @hidden */
private _needUVs: boolean;
->>>>>>> e0d205794def4ad96793ee06bf383169b9adecd1
+        [id: string]: any;
         /**
          * Specifies if the material needs to be re-calculated
          */
@@ -9775,10 +9784,19 @@ declare module BABYLON {
          */
         onBeforeShadowMapRenderObservable: Observable<Effect>;
         /**
+         * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
+         */
+        onAfterShadowMapRenderObservable: Observable<Effect>;
+        /**
          * Observable triggered before a mesh is rendered in the shadow map.
          * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
          */
         onBeforeShadowMapRenderMeshObservable: Observable<Mesh>;
+        /**
+         * Observable triggered after a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
+         */
+        onAfterShadowMapRenderMeshObservable: Observable<Mesh>;
         private _bias;
         /**
          * Gets the bias: offset applied on the depth preventing acnea (in light direction).
@@ -9938,6 +9956,8 @@ declare module BABYLON {
         */
         contactHardeningLightSizeUVRatio: number;
         private _darkness;
+        /** Gets or sets the actual darkness of a shadow */
+        darkness: number;
         /**
          * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
          * 0 means strongest and 1 would means no shadow.
@@ -9951,6 +9971,8 @@ declare module BABYLON {
          */
         setDarkness(darkness: number): ShadowGenerator;
         private _transparencyShadow;
+        /** Gets or sets the ability to have transparent shadow  */
+        transparencyShadow: boolean;
         /**
          * Sets the ability to have transparent shadow (boolean).
          * @param transparent True if transparent else False
@@ -9970,6 +9992,11 @@ declare module BABYLON {
          */
         getShadowMapForRendering(): Nullable<RenderTargetTexture>;
         /**
+         * Gets the class name of that object
+         * @returns "ShadowGenerator"
+         */
+        getClassName(): string;
+        /**
          * Helper function to add a mesh and its descendants to the list of shadow casters.
          * @param mesh Mesh to add
          * @param includeDescendants boolean indicating if the descendants should be added. Default to true
@@ -10480,6 +10507,13 @@ declare module BABYLON {
          * Internal only - manager for action
          * @hidden
          */
private _actionManager: AbstractActionManager;
+        /**
+         * Adds action to chain of actions, may be a DoNothingAction
+         * @param action defines the next action to execute
+         * @returns The action passed in
+         * @see https://www.babylonjs-playground.com/#1T30HR#0
+         */
+        then(action: IAction): IAction;
     }
     /**
      * The action to be carried out following a trigger
@@ -13734,185 +13768,6 @@ declare module BABYLON {
 declare module BABYLON {
         interface AbstractScene {
             /**
-             * The list of layers (background and foreground) of the scene
-             */
-            layers: Array<Layer>;
-        }
-    /**
-     * Defines the layer scene component responsible to manage any layers
-     * in a given scene.
-     */
-    export class LayerSceneComponent implements ISceneComponent {
-        /**
-         * The component name helpfull to identify the component in the list of scene components.
-         */
-        readonly name: string;
-        /**
-         * The scene the component belongs to.
-         */
-        scene: Scene;
-        private _engine;
-        /**
-         * Creates a new instance of the component for the given scene
-         * @param scene Defines the scene to register the component in
-         */
-        constructor(scene: Scene);
-        /**
-         * Registers the component in a given scene
-         */
-        register(): void;
-        /**
-         * Rebuilds the elements related to this component in case of
-         * context lost for instance.
-         */
-        rebuild(): void;
-        /**
-         * Disposes the component and the associated ressources.
-         */
-        dispose(): void;
-        private _draw;
-        private _drawCameraPredicate;
-        private _drawCameraBackground;
-        private _drawCameraForeground;
-        private _drawRenderTargetPredicate;
-        private _drawRenderTargetBackground;
-        private _drawRenderTargetForeground;
-    }
-}
-declare module BABYLON {
-    /** @hidden */
-    export var layerPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
-    export var layerVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a full screen 2d layer.
-     * This can be useful to display a picture in the  background of your scene for instance.
-     * @see https://www.babylonjs-playground.com/#08A2BS#1
-     */
-    export class Layer {
-        /**
-         * Define the name of the layer.
-         */
-        name: string;
-        /**
-         * Define the texture the layer should display.
-         */
-        texture: Nullable<Texture>;
-        /**
-         * Is the layer in background or foreground.
-         */
-        isBackground: boolean;
-        /**
-         * Define the color of the layer (instead of texture).
-         */
-        color: Color4;
-        /**
-         * Define the scale of the layer in order to zoom in out of the texture.
-         */
-        scale: Vector2;
-        /**
-         * Define an offset for the layer in order to shift the texture.
-         */
-        offset: Vector2;
-        /**
-         * Define the alpha blending mode used in the layer in case the texture or color has an alpha.
-         */
-        alphaBlendingMode: number;
-        /**
-         * Define if the layer should alpha test or alpha blend with the rest of the scene.
-         * Alpha test will not mix with the background color in case of transparency.
-         * It will either use the texture color or the background depending on the alpha value of the current pixel.
-         */
-        alphaTest: boolean;
-        /**
-         * Define a mask to restrict the layer to only some of the scene cameras.
-         */
-        layerMask: number;
-        /**
-         * Define the list of render target the layer is visible into.
-         */
-        renderTargetTextures: RenderTargetTexture[];
-        /**
-         * Define if the layer is only used in renderTarget or if it also
-         * renders in the main frame buffer of the canvas.
-         */
-        renderOnlyInRenderTargetTextures: boolean;
-        private _scene;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _alphaTestEffect;
-        /**
-         * An event triggered when the layer is disposed.
-         */
-        onDisposeObservable: Observable<Layer>;
-        private _onDisposeObserver;
-        /**
-         * Back compatibility with callback before the onDisposeObservable existed.
-         * The set callback will be triggered when the layer has been disposed.
-         */
-        onDispose: () => void;
-        /**
-        * An event triggered before rendering the scene
-        */
-        onBeforeRenderObservable: Observable<Layer>;
-        private _onBeforeRenderObserver;
-        /**
-         * Back compatibility with callback before the onBeforeRenderObservable existed.
-         * The set callback will be triggered just before rendering the layer.
-         */
-        onBeforeRender: () => void;
-        /**
-        * An event triggered after rendering the scene
-        */
-        onAfterRenderObservable: Observable<Layer>;
-        private _onAfterRenderObserver;
-        /**
-         * Back compatibility with callback before the onAfterRenderObservable existed.
-         * The set callback will be triggered just after rendering the layer.
-         */
-        onAfterRender: () => void;
-        /**
-         * Instantiates a new layer.
-         * This represents a full screen 2d layer.
-         * This can be useful to display a picture in the  background of your scene for instance.
-         * @see https://www.babylonjs-playground.com/#08A2BS#1
-         * @param name Define the name of the layer in the scene
-         * @param imgUrl Define the url of the texture to display in the layer
-         * @param scene Define the scene the layer belongs to
-         * @param isBackground Defines whether the layer is displayed in front or behind the scene
-         * @param color Defines a color for the layer
-         */
-        constructor(
-        /**
-         * Define the name of the layer.
-         */
-        name: string, imgUrl: Nullable<string>, scene: Nullable<Scene>, isBackground?: boolean, color?: Color4);
-        private _createIndexBuffer;
-        /** @hidden */
private _rebuild(): void;
-        /**
-         * Renders the layer in the scene.
-         */
-        render(): void;
-        /**
-         * Disposes and releases the associated ressources.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
-        interface AbstractScene {
-            /**
              * The list of procedural textures added to the scene
              * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures
              */
@@ -16964,11 +16819,11 @@ declare module BABYLON {
         /**
          * If vertex color should be applied to the mesh
          */
-        useVertexColor?: boolean | undefined;
+        readonly useVertexColor?: boolean | undefined;
         /**
          * If vertex alpha should be applied to the mesh
          */
-        useVertexAlpha?: boolean | undefined;
+        readonly useVertexAlpha?: boolean | undefined;
         /**
          * Color of the line (Default: White)
          */
@@ -16984,6 +16839,7 @@ declare module BABYLON {
          */
         intersectionThreshold: number;
         private _colorShader;
+        private color4;
         /**
          * Creates a new LinesMesh
          * @param name defines the name
@@ -17219,6 +17075,7 @@ declare module BABYLON {
      */
     export class RenderingGroup {
         index: number;
+        private static _zeroVector;
         private _scene;
         private _opaqueSubMeshes;
         private _transparentSubMeshes;
@@ -20807,6 +20664,7 @@ declare module BABYLON {
          * Returns the mesh VertexBuffer object from the requested `kind`
          * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -20825,6 +20683,7 @@ declare module BABYLON {
          * Tests if a specific vertex buffer is associated with this mesh
          * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -20861,6 +20720,7 @@ declare module BABYLON {
          * Returns a string which contains the list of existing `kinds` of Vertex Data associated with this mesh.
          * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -22136,6 +21996,7 @@ declare module BABYLON {
         forceCompilationAsync(mesh: AbstractMesh, options?: Partial<{
             clipPlane: boolean;
         }>): Promise<void>;
+        private static readonly _AllDirtyCallBack;
         private static readonly _ImageProcessingDirtyCallBack;
         private static readonly _TextureDirtyCallBack;
         private static readonly _FresnelDirtyCallBack;
@@ -22157,6 +22018,10 @@ declare module BABYLON {
          */
         protected _markAllSubMeshesAsDirty(func: (defines: MaterialDefines) => void): void;
         /**
+     * Indicates that we need to re-calculated for all submeshes
+     */
+        protected _markAllSubMeshesAsAllDirty(): void;
+        /**
          * Indicates that image processing needs to be re-calculated for all submeshes
          */
         protected _markAllSubMeshesAsImageProcessingDirty(): void;
@@ -35218,7 +35083,10 @@ declare module BABYLON {
      */
     export class PointerDragBehavior implements Behavior<AbstractMesh> {
         private static _AnyMouseID;
-        private _attachedNode;
+        /**
+         * Abstract mesh the behavior is set on
+         */
+        attachedNode: AbstractMesh;
         private _dragPlane;
         private _scene;
         private _pointerObserver;
@@ -39094,6 +38962,7 @@ declare module BABYLON {
          * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
          * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
          * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+         * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
          * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
          * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
          * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -39125,6 +38994,7 @@ declare module BABYLON {
             updatable?: boolean;
             hasRings?: boolean;
             enclose?: boolean;
+            cap?: number;
             sideOrientation?: number;
             frontUVs?: Vector4;
             backUVs?: Vector4;
@@ -44512,7 +44382,7 @@ declare module BABYLON {
      *
      * This offers the main features of a standard PBR material.
      * For more information, please refer to the documentation :
-     * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+     * https://doc.babylonjs.com/how_to/physically_based_rendering
      */
     export abstract class PBRBaseMaterial extends PushMaterial {
         /**
@@ -45014,7 +44884,7 @@ declare module BABYLON {
      *
      * This offers the main features of a standard PBR material.
      * For more information, please refer to the documentation :
-     * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+     * https://doc.babylonjs.com/how_to/physically_based_rendering
      */
     export class PBRMaterial extends PBRBaseMaterial {
         /**
@@ -47032,6 +46902,185 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+        interface AbstractScene {
+            /**
+             * The list of layers (background and foreground) of the scene
+             */
+            layers: Array<Layer>;
+        }
+    /**
+     * Defines the layer scene component responsible to manage any layers
+     * in a given scene.
+     */
+    export class LayerSceneComponent implements ISceneComponent {
+        /**
+         * The component name helpfull to identify the component in the list of scene components.
+         */
+        readonly name: string;
+        /**
+         * The scene the component belongs to.
+         */
+        scene: Scene;
+        private _engine;
+        /**
+         * Creates a new instance of the component for the given scene
+         * @param scene Defines the scene to register the component in
+         */
+        constructor(scene: Scene);
+        /**
+         * Registers the component in a given scene
+         */
+        register(): void;
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        rebuild(): void;
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        dispose(): void;
+        private _draw;
+        private _drawCameraPredicate;
+        private _drawCameraBackground;
+        private _drawCameraForeground;
+        private _drawRenderTargetPredicate;
+        private _drawRenderTargetBackground;
+        private _drawRenderTargetForeground;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var layerPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var layerVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a full screen 2d layer.
+     * This can be useful to display a picture in the  background of your scene for instance.
+     * @see https://www.babylonjs-playground.com/#08A2BS#1
+     */
+    export class Layer {
+        /**
+         * Define the name of the layer.
+         */
+        name: string;
+        /**
+         * Define the texture the layer should display.
+         */
+        texture: Nullable<Texture>;
+        /**
+         * Is the layer in background or foreground.
+         */
+        isBackground: boolean;
+        /**
+         * Define the color of the layer (instead of texture).
+         */
+        color: Color4;
+        /**
+         * Define the scale of the layer in order to zoom in out of the texture.
+         */
+        scale: Vector2;
+        /**
+         * Define an offset for the layer in order to shift the texture.
+         */
+        offset: Vector2;
+        /**
+         * Define the alpha blending mode used in the layer in case the texture or color has an alpha.
+         */
+        alphaBlendingMode: number;
+        /**
+         * Define if the layer should alpha test or alpha blend with the rest of the scene.
+         * Alpha test will not mix with the background color in case of transparency.
+         * It will either use the texture color or the background depending on the alpha value of the current pixel.
+         */
+        alphaTest: boolean;
+        /**
+         * Define a mask to restrict the layer to only some of the scene cameras.
+         */
+        layerMask: number;
+        /**
+         * Define the list of render target the layer is visible into.
+         */
+        renderTargetTextures: RenderTargetTexture[];
+        /**
+         * Define if the layer is only used in renderTarget or if it also
+         * renders in the main frame buffer of the canvas.
+         */
+        renderOnlyInRenderTargetTextures: boolean;
+        private _scene;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _alphaTestEffect;
+        /**
+         * An event triggered when the layer is disposed.
+         */
+        onDisposeObservable: Observable<Layer>;
+        private _onDisposeObserver;
+        /**
+         * Back compatibility with callback before the onDisposeObservable existed.
+         * The set callback will be triggered when the layer has been disposed.
+         */
+        onDispose: () => void;
+        /**
+        * An event triggered before rendering the scene
+        */
+        onBeforeRenderObservable: Observable<Layer>;
+        private _onBeforeRenderObserver;
+        /**
+         * Back compatibility with callback before the onBeforeRenderObservable existed.
+         * The set callback will be triggered just before rendering the layer.
+         */
+        onBeforeRender: () => void;
+        /**
+        * An event triggered after rendering the scene
+        */
+        onAfterRenderObservable: Observable<Layer>;
+        private _onAfterRenderObserver;
+        /**
+         * Back compatibility with callback before the onAfterRenderObservable existed.
+         * The set callback will be triggered just after rendering the layer.
+         */
+        onAfterRender: () => void;
+        /**
+         * Instantiates a new layer.
+         * This represents a full screen 2d layer.
+         * This can be useful to display a picture in the  background of your scene for instance.
+         * @see https://www.babylonjs-playground.com/#08A2BS#1
+         * @param name Define the name of the layer in the scene
+         * @param imgUrl Define the url of the texture to display in the layer
+         * @param scene Define the scene the layer belongs to
+         * @param isBackground Defines whether the layer is displayed in front or behind the scene
+         * @param color Defines a color for the layer
+         */
+        constructor(
+        /**
+         * Define the name of the layer.
+         */
+        name: string, imgUrl: Nullable<string>, scene: Nullable<Scene>, isBackground?: boolean, color?: Color4);
+        private _createIndexBuffer;
+        /** @hidden */
private _rebuild(): void;
+        /**
+         * Renders the layer in the scene.
+         */
+        render(): void;
+        /**
+         * Disposes and releases the associated ressources.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
     /** @hidden */
     export var lensFlarePixelShader: {
         name: string;
@@ -49061,7 +49110,68 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-<<<<<<< HEAD
+     * Defines the options related to the creation of an HtmlElementTexture
+     */
+    export interface IHtmlElementTextureOptions {
+        /**
+         * Defines wether mip maps should be created or not.
+         */
+        generateMipMaps?: boolean;
+        /**
+         * Defines the sampling mode of the texture.
+         */
+        samplingMode?: number;
+        /**
+         * Defines the engine instance to use the texture with. It is not mandatory if you define a scene.
+         */
+        engine: Nullable<Engine>;
+        /**
+         * Defines the scene the texture belongs to. It is not mandatory if you define an engine.
+         */
+        scene: Nullable<Scene>;
+    }
+    /**
+     * This represents the smallest workload to use an already existing element (Canvas or Video) as a texture.
+     * To be as efficient as possible depending on your constraints nothing aside the first upload
+     * is automatically managed.
+     * It is a cheap VideoTexture or DynamicTexture if you prefer to keep full control of the elements
+     * in your application.
+     *
+     * As the update is not automatic, you need to call them manually.
+     */
+    export class HtmlElementTexture extends BaseTexture {
+        /**
+         * The texture URL.
+         */
+        element: HTMLVideoElement | HTMLCanvasElement;
+        private static readonly DefaultOptions;
+        private _textureMatrix;
+        private _engine;
+        private _isVideo;
+        private _generateMipMaps;
+        private _samplingMode;
+        /**
+         * Instantiates a HtmlElementTexture from the following parameters.
+         *
+         * @param name Defines the name of the texture
+         * @param element Defines the video or canvas the texture is filled with
+         * @param options Defines the other none mandatory texture creation options
+         */
+        constructor(name: string, element: HTMLVideoElement | HTMLCanvasElement, options: IHtmlElementTextureOptions);
+        private _createInternalTexture;
+        /**
+         * Returns the texture matrix used in most of the material.
+         */
+        getTextureMatrix(): Matrix;
+        /**
+         * Updates the content of the texture.
+         * @param invertY Defines wether the texture should be inverted on Y (false by default on video and true on canvas)
+         */
+        update(invertY?: Nullable<boolean>): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Enum used to define the target of a block
      */
     export enum NodeMaterialBlockTargets {
@@ -49240,13 +49350,13 @@ declare module BABYLON {
          * Shared data between multiple NodeMaterialBuildState instances
          */
         sharedData: NodeMaterialBuildStateSharedData;
-        /** @hidden */
vertexState: NodeMaterialBuildState;
+        /** @hidden */
private _vertexState: NodeMaterialBuildState;
         private _attributeDeclaration;
         private _uniformDeclaration;
         private _samplerDeclaration;
         private _varyingTransfer;
         private _repeatableContentAnchorIndex;
-        /** @hidden */
builtCompilationString: string;
+        /** @hidden */
private _builtCompilationString: string;
         /**
          * Gets the emitted compilation strings
          */
@@ -49257,18 +49367,18 @@ declare module BABYLON {
          */
         finalize(state: NodeMaterialBuildState): void;
         /** @hidden */
protected readonly _repeatableContentAnchor: string;
-        /** @hidden */
getFreeVariableName(prefix: string): string;
-        /** @hidden */
getFreeDefineName(prefix: string): string;
-        /** @hidden */
excludeVariableName(name: string): void;
-        /** @hidden */
getGLType(type: NodeMaterialBlockConnectionPointTypes): string;
-        /** @hidden */
emitFunction(name: string, code: string, comments: string): void;
-        /** @hidden */
emitCodeFromInclude(includeName: string, comments: string, options?: {
+        /** @hidden */
private _getFreeVariableName(prefix: string): string;
+        /** @hidden */
private _getFreeDefineName(prefix: string): string;
+        /** @hidden */
private _excludeVariableName(name: string): void;
+        /** @hidden */
private _getGLType(type: NodeMaterialBlockConnectionPointTypes): string;
+        /** @hidden */
private _emitFunction(name: string, code: string, comments: string): void;
+        /** @hidden */
private _emitCodeFromInclude(includeName: string, comments: string, options?: {
             replaceStrings?: {
                 search: RegExp;
                 replace: string;
             }[];
         }): string;
-        /** @hidden */
emitFunctionFromInclude(includeName: string, comments: string, options?: {
+        /** @hidden */
private _emitFunctionFromInclude(includeName: string, comments: string, options?: {
             repeatKey?: string;
             removeAttributes?: boolean;
             removeUniforms?: boolean;
@@ -49279,9 +49389,9 @@ declare module BABYLON {
                 replace: string;
             }[];
         }): void;
-        /** @hidden */
emitVaryings(point: NodeMaterialConnectionPoint, define?: string, force?: boolean, fromFragment?: boolean, replacementName?: string): void;
+        /** @hidden */
private _emitVaryings(point: NodeMaterialConnectionPoint, define?: string, force?: boolean, fromFragment?: boolean, replacementName?: string): void;
         private _emitDefine;
-        /** @hidden */
emitUniformOrAttributes(point: NodeMaterialConnectionPoint, define?: string): void;
+        /** @hidden */
private _emitUniformOrAttributes(point: NodeMaterialConnectionPoint, define?: string): void;
     }
 }
 declare module BABYLON {
@@ -49360,12 +49470,10 @@ declare module BABYLON {
         onBuildObservable: Observable<NodeMaterial>;
         /**
          * Gets or sets the root nodes of the material vertex shader
-         */
-        private _vertexOutputNodes;
+         */
private _vertexOutputNodes: NodeMaterialBlock[];
         /**
          * Gets or sets the root nodes of the material fragment (pixel) shader
-         */
-        private _fragmentOutputNodes;
+         */
private _fragmentOutputNodes: NodeMaterialBlock[];
         /** Gets or sets options to control the node material overall behavior */
         options: INodeMaterialOptions;
         /**
@@ -49501,10 +49609,8 @@ declare module BABYLON {
         private _buildId;
         private _target;
         private _isFinalMerger;
-        /** @hidden */
-        protected _inputs: NodeMaterialConnectionPoint[];
-        /** @hidden */
-        protected _outputs: NodeMaterialConnectionPoint[];
+        /** @hidden */
private _inputs: NodeMaterialConnectionPoint[];
+        /** @hidden */
private _outputs: NodeMaterialConnectionPoint[];
         /**
          * Gets or sets the name of the block
          */
@@ -49655,14 +49761,14 @@ declare module BABYLON {
      * Defines a connection point for a block
      */
     export class NodeMaterialConnectionPoint {
-        private _ownerBlock;
-        private _connectedPoint;
+        /** @hidden */
private _ownerBlock: NodeMaterialBlock;
+        /** @hidden */
private _connectedPoint: Nullable<NodeMaterialConnectionPoint>;
         private _associatedVariableName;
         private _endpoints;
         private _storedValue;
         private _valueCallback;
         private _isVarying;
-        /** @hidden */
wellKnownValue: Nullable<NodeMaterialWellKnownValues>;
+        /** @hidden */
private _wellKnownValue: Nullable<NodeMaterialWellKnownValues>;
         /**
          * Gets or sets the connection point type (default is float)
          */
@@ -50101,71 +50207,10 @@ declare module BABYLON {
          */
         readonly input: NodeMaterialConnectionPoint;
         protected _buildBlock(state: NodeMaterialBuildState): this;
-=======
-     * Defines the options related to the creation of an HtmlElementTexture
-     */
-    export interface IHtmlElementTextureOptions {
-        /**
-         * Defines wether mip maps should be created or not.
-         */
-        generateMipMaps?: boolean;
-        /**
-         * Defines the sampling mode of the texture.
-         */
-        samplingMode?: number;
-        /**
-         * Defines the engine instance to use the texture with. It is not mandatory if you define a scene.
-         */
-        engine: Nullable<Engine>;
-        /**
-         * Defines the scene the texture belongs to. It is not mandatory if you define an engine.
-         */
-        scene: Nullable<Scene>;
-    }
-    /**
-     * This represents the smallest workload to use an already existing element (Canvas or Video) as a texture.
-     * To be as efficient as possible depending on your constraints nothing aside the first upload
-     * is automatically managed.
-     * It is a cheap VideoTexture or DynamicTexture if you prefer to keep full control of the elements
-     * in your application.
-     *
-     * As the update is not automatic, you need to call them manually.
-     */
-    export class HtmlElementTexture extends BaseTexture {
-        /**
-         * The texture URL.
-         */
-        element: HTMLVideoElement | HTMLCanvasElement;
-        private static readonly DefaultOptions;
-        private _textureMatrix;
-        private _engine;
-        private _isVideo;
-        private _generateMipMaps;
-        private _samplingMode;
-        /**
-         * Instantiates a HtmlElementTexture from the following parameters.
-         *
-         * @param name Defines the name of the texture
-         * @param element Defines the video or canvas the texture is filled with
-         * @param options Defines the other none mandatory texture creation options
-         */
-        constructor(name: string, element: HTMLVideoElement | HTMLCanvasElement, options: IHtmlElementTextureOptions);
-        private _createInternalTexture;
-        /**
-         * Returns the texture matrix used in most of the material.
-         */
-        getTextureMatrix(): Matrix;
-        /**
-         * Updates the content of the texture.
-         * @param invertY Defines wether the texture should be inverted on Y (false by default on video and true on canvas)
-         */
-        update(invertY?: Nullable<boolean>): void;
->>>>>>> e0d205794def4ad96793ee06bf383169b9adecd1
     }
 }
 declare module BABYLON {
     /**
-<<<<<<< HEAD
      * Block used to read a texture from a sampler
      */
     export class TextureBlock extends NodeMaterialBlock {
@@ -50483,7 +50528,10 @@ declare module BABYLON {
          */
         getClassName(): string;
         protected _buildBlock(state: NodeMaterialBuildState): this;
-=======
+    }
+}
+declare module BABYLON {
+    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {
@@ -50505,7 +50553,6 @@ declare module BABYLON {
          */
         push(action: (worker: Worker, onComplete: () => void) => void): void;
         private _execute;
->>>>>>> e0d205794def4ad96793ee06bf383169b9adecd1
     }
 }
 declare module BABYLON {
@@ -51380,6 +51427,7 @@ declare module BABYLON {
          * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
          * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
          * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+         * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
          * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
          * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
          * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -51411,6 +51459,7 @@ declare module BABYLON {
             updatable?: boolean;
             hasRings?: boolean;
             enclose?: boolean;
+            cap?: number;
             sideOrientation?: number;
             frontUVs?: Vector4;
             backUVs?: Vector4;
@@ -60008,8 +60057,6 @@ declare module BABYLON.GUI {
         private _drawGradientSquare;
         private _drawCircle;
         private _createColorWheelCanvas;
-        private _RGBtoHSV;
-        private _HSVtoRGB;
         /** @hidden */
private _draw(context: CanvasRenderingContext2D): void;
         private _pointerIsDown;
         private _updateValueFromPointer;

+ 4 - 1
Playground/css/index.css

@@ -28,12 +28,15 @@ body {
     display: grid;
     grid-template-rows: 100%;
     grid-template-columns: 100%;
+    align-items: center;
 }
 
 #waitLogo {
     grid-column: 1;
     grid-row: 1;
-    margin: 25%;
+    margin: auto;
+    width: 40%;
+    height: 40%;
 }
 
 #waitSpinner {

+ 247 - 185
dist/preview release/babylon.d.ts

@@ -460,6 +460,16 @@ declare module BABYLON {
          */
         toLinearSpace(): Color3;
         /**
+         * Converts current color in rgb space to HSV values
+         * @returns a new color3 representing the HSV values
+         */
+        toHSV(): Color3;
+        /**
+         * Converts current color in rgb space to HSV values
+         * @param result defines the Color3 where to store the HSV values
+         */
+        toHSVToRef(result: Color3): void;
+        /**
          * Converts the Color3 values to linear space and stores the result in "convertedColor"
          * @param convertedColor defines the Color3 object where to store the linear space version
          * @returns the unmodified Color3
@@ -478,6 +488,14 @@ declare module BABYLON {
         toGammaSpaceToRef(convertedColor: Color3): Color3;
         private static _BlackReadOnly;
         /**
+         * Convert Hue, saturation and value to a Color3 (RGB)
+         * @param hue defines the hue
+         * @param saturation defines the saturation
+         * @param value defines the value
+         * @param result defines the Color3 where to store the RGB values
+         */
+        static HSVtoRGBToRef(hue: number, saturation: number, value: number, result: Color3): void;
+        /**
          * Creates a new Color3 from the string containing valid hexadecimal values
          * @param hex defines a string containing valid hexadecimal values
          * @returns a new Color3 object
@@ -1217,6 +1235,7 @@ declare module BABYLON {
          */
         z: number;
         private static _UpReadOnly;
+        private static _ZeroReadOnly;
         /**
          * Creates a new Vector3 object from the given x, y, z (floats) coordinates.
          * @param x defines the first coordinates (on X axis)
@@ -1641,6 +1660,10 @@ declare module BABYLON {
          */
         static readonly UpReadOnly: DeepImmutable<Vector3>;
         /**
+         * Gets a zero Vector3 that must not be updated
+         */
+        static readonly ZeroReadOnly: DeepImmutable<Vector3>;
+        /**
          * Returns a new Vector3 set to (0.0, -1.0, 0.0)
          * @returns a new down Vector3
          */
@@ -9885,10 +9908,19 @@ declare module BABYLON {
          */
         onBeforeShadowMapRenderObservable: Observable<Effect>;
         /**
+         * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
+         */
+        onAfterShadowMapRenderObservable: Observable<Effect>;
+        /**
          * Observable triggered before a mesh is rendered in the shadow map.
          * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
          */
         onBeforeShadowMapRenderMeshObservable: Observable<Mesh>;
+        /**
+         * Observable triggered after a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
+         */
+        onAfterShadowMapRenderMeshObservable: Observable<Mesh>;
         private _bias;
         /**
          * Gets the bias: offset applied on the depth preventing acnea (in light direction).
@@ -10048,6 +10080,8 @@ declare module BABYLON {
         */
         contactHardeningLightSizeUVRatio: number;
         private _darkness;
+        /** Gets or sets the actual darkness of a shadow */
+        darkness: number;
         /**
          * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
          * 0 means strongest and 1 would means no shadow.
@@ -10061,6 +10095,8 @@ declare module BABYLON {
          */
         setDarkness(darkness: number): ShadowGenerator;
         private _transparencyShadow;
+        /** Gets or sets the ability to have transparent shadow  */
+        transparencyShadow: boolean;
         /**
          * Sets the ability to have transparent shadow (boolean).
          * @param transparent True if transparent else False
@@ -10080,6 +10116,11 @@ declare module BABYLON {
          */
         getShadowMapForRendering(): Nullable<RenderTargetTexture>;
         /**
+         * Gets the class name of that object
+         * @returns "ShadowGenerator"
+         */
+        getClassName(): string;
+        /**
          * Helper function to add a mesh and its descendants to the list of shadow casters.
          * @param mesh Mesh to add
          * @param includeDescendants boolean indicating if the descendants should be added. Default to true
@@ -10601,6 +10642,13 @@ declare module BABYLON {
          * @hidden
          */
         _actionManager: AbstractActionManager;
+        /**
+         * Adds action to chain of actions, may be a DoNothingAction
+         * @param action defines the next action to execute
+         * @returns The action passed in
+         * @see https://www.babylonjs-playground.com/#1T30HR#0
+         */
+        then(action: IAction): IAction;
     }
     /**
      * The action to be carried out following a trigger
@@ -13943,186 +13991,6 @@ declare module BABYLON {
 declare module BABYLON {
         interface AbstractScene {
             /**
-             * The list of layers (background and foreground) of the scene
-             */
-            layers: Array<Layer>;
-        }
-    /**
-     * Defines the layer scene component responsible to manage any layers
-     * in a given scene.
-     */
-    export class LayerSceneComponent implements ISceneComponent {
-        /**
-         * The component name helpfull to identify the component in the list of scene components.
-         */
-        readonly name: string;
-        /**
-         * The scene the component belongs to.
-         */
-        scene: Scene;
-        private _engine;
-        /**
-         * Creates a new instance of the component for the given scene
-         * @param scene Defines the scene to register the component in
-         */
-        constructor(scene: Scene);
-        /**
-         * Registers the component in a given scene
-         */
-        register(): void;
-        /**
-         * Rebuilds the elements related to this component in case of
-         * context lost for instance.
-         */
-        rebuild(): void;
-        /**
-         * Disposes the component and the associated ressources.
-         */
-        dispose(): void;
-        private _draw;
-        private _drawCameraPredicate;
-        private _drawCameraBackground;
-        private _drawCameraForeground;
-        private _drawRenderTargetPredicate;
-        private _drawRenderTargetBackground;
-        private _drawRenderTargetForeground;
-    }
-}
-declare module BABYLON {
-    /** @hidden */
-    export var layerPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
-    export var layerVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a full screen 2d layer.
-     * This can be useful to display a picture in the  background of your scene for instance.
-     * @see https://www.babylonjs-playground.com/#08A2BS#1
-     */
-    export class Layer {
-        /**
-         * Define the name of the layer.
-         */
-        name: string;
-        /**
-         * Define the texture the layer should display.
-         */
-        texture: Nullable<Texture>;
-        /**
-         * Is the layer in background or foreground.
-         */
-        isBackground: boolean;
-        /**
-         * Define the color of the layer (instead of texture).
-         */
-        color: Color4;
-        /**
-         * Define the scale of the layer in order to zoom in out of the texture.
-         */
-        scale: Vector2;
-        /**
-         * Define an offset for the layer in order to shift the texture.
-         */
-        offset: Vector2;
-        /**
-         * Define the alpha blending mode used in the layer in case the texture or color has an alpha.
-         */
-        alphaBlendingMode: number;
-        /**
-         * Define if the layer should alpha test or alpha blend with the rest of the scene.
-         * Alpha test will not mix with the background color in case of transparency.
-         * It will either use the texture color or the background depending on the alpha value of the current pixel.
-         */
-        alphaTest: boolean;
-        /**
-         * Define a mask to restrict the layer to only some of the scene cameras.
-         */
-        layerMask: number;
-        /**
-         * Define the list of render target the layer is visible into.
-         */
-        renderTargetTextures: RenderTargetTexture[];
-        /**
-         * Define if the layer is only used in renderTarget or if it also
-         * renders in the main frame buffer of the canvas.
-         */
-        renderOnlyInRenderTargetTextures: boolean;
-        private _scene;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _alphaTestEffect;
-        /**
-         * An event triggered when the layer is disposed.
-         */
-        onDisposeObservable: Observable<Layer>;
-        private _onDisposeObserver;
-        /**
-         * Back compatibility with callback before the onDisposeObservable existed.
-         * The set callback will be triggered when the layer has been disposed.
-         */
-        onDispose: () => void;
-        /**
-        * An event triggered before rendering the scene
-        */
-        onBeforeRenderObservable: Observable<Layer>;
-        private _onBeforeRenderObserver;
-        /**
-         * Back compatibility with callback before the onBeforeRenderObservable existed.
-         * The set callback will be triggered just before rendering the layer.
-         */
-        onBeforeRender: () => void;
-        /**
-        * An event triggered after rendering the scene
-        */
-        onAfterRenderObservable: Observable<Layer>;
-        private _onAfterRenderObserver;
-        /**
-         * Back compatibility with callback before the onAfterRenderObservable existed.
-         * The set callback will be triggered just after rendering the layer.
-         */
-        onAfterRender: () => void;
-        /**
-         * Instantiates a new layer.
-         * This represents a full screen 2d layer.
-         * This can be useful to display a picture in the  background of your scene for instance.
-         * @see https://www.babylonjs-playground.com/#08A2BS#1
-         * @param name Define the name of the layer in the scene
-         * @param imgUrl Define the url of the texture to display in the layer
-         * @param scene Define the scene the layer belongs to
-         * @param isBackground Defines whether the layer is displayed in front or behind the scene
-         * @param color Defines a color for the layer
-         */
-        constructor(
-        /**
-         * Define the name of the layer.
-         */
-        name: string, imgUrl: Nullable<string>, scene: Nullable<Scene>, isBackground?: boolean, color?: Color4);
-        private _createIndexBuffer;
-        /** @hidden */
-        _rebuild(): void;
-        /**
-         * Renders the layer in the scene.
-         */
-        render(): void;
-        /**
-         * Disposes and releases the associated ressources.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
-        interface AbstractScene {
-            /**
              * The list of procedural textures added to the scene
              * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures
              */
@@ -17232,11 +17100,11 @@ declare module BABYLON {
         /**
          * If vertex color should be applied to the mesh
          */
-        useVertexColor?: boolean | undefined;
+        readonly useVertexColor?: boolean | undefined;
         /**
          * If vertex alpha should be applied to the mesh
          */
-        useVertexAlpha?: boolean | undefined;
+        readonly useVertexAlpha?: boolean | undefined;
         /**
          * Color of the line (Default: White)
          */
@@ -17252,6 +17120,7 @@ declare module BABYLON {
          */
         intersectionThreshold: number;
         private _colorShader;
+        private color4;
         /**
          * Creates a new LinesMesh
          * @param name defines the name
@@ -17492,6 +17361,7 @@ declare module BABYLON {
      */
     export class RenderingGroup {
         index: number;
+        private static _zeroVector;
         private _scene;
         private _opaqueSubMeshes;
         private _transparentSubMeshes;
@@ -21131,6 +21001,7 @@ declare module BABYLON {
          * Returns the mesh VertexBuffer object from the requested `kind`
          * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -21149,6 +21020,7 @@ declare module BABYLON {
          * Tests if a specific vertex buffer is associated with this mesh
          * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -21185,6 +21057,7 @@ declare module BABYLON {
          * Returns a string which contains the list of existing `kinds` of Vertex Data associated with this mesh.
          * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
          * - VertexBuffer.PositionKind
+         * - VertexBuffer.NormalKind
          * - VertexBuffer.UVKind
          * - VertexBuffer.UV2Kind
          * - VertexBuffer.UV3Kind
@@ -35895,7 +35768,10 @@ declare module BABYLON {
      */
     export class PointerDragBehavior implements Behavior<AbstractMesh> {
         private static _AnyMouseID;
-        private _attachedNode;
+        /**
+         * Abstract mesh the behavior is set on
+         */
+        attachedNode: AbstractMesh;
         private _dragPlane;
         private _scene;
         private _pointerObserver;
@@ -39792,6 +39668,7 @@ declare module BABYLON {
          * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
          * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
          * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+         * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
          * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
          * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
          * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -39823,6 +39700,7 @@ declare module BABYLON {
             updatable?: boolean;
             hasRings?: boolean;
             enclose?: boolean;
+            cap?: number;
             sideOrientation?: number;
             frontUVs?: Vector4;
             backUVs?: Vector4;
@@ -45257,7 +45135,7 @@ declare module BABYLON {
      *
      * This offers the main features of a standard PBR material.
      * For more information, please refer to the documentation :
-     * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+     * https://doc.babylonjs.com/how_to/physically_based_rendering
      */
     export abstract class PBRBaseMaterial extends PushMaterial {
         /**
@@ -45759,7 +45637,7 @@ declare module BABYLON {
      *
      * This offers the main features of a standard PBR material.
      * For more information, please refer to the documentation :
-     * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+     * https://doc.babylonjs.com/how_to/physically_based_rendering
      */
     export class PBRMaterial extends PBRBaseMaterial {
         /**
@@ -47782,6 +47660,186 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+        interface AbstractScene {
+            /**
+             * The list of layers (background and foreground) of the scene
+             */
+            layers: Array<Layer>;
+        }
+    /**
+     * Defines the layer scene component responsible to manage any layers
+     * in a given scene.
+     */
+    export class LayerSceneComponent implements ISceneComponent {
+        /**
+         * The component name helpfull to identify the component in the list of scene components.
+         */
+        readonly name: string;
+        /**
+         * The scene the component belongs to.
+         */
+        scene: Scene;
+        private _engine;
+        /**
+         * Creates a new instance of the component for the given scene
+         * @param scene Defines the scene to register the component in
+         */
+        constructor(scene: Scene);
+        /**
+         * Registers the component in a given scene
+         */
+        register(): void;
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        rebuild(): void;
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        dispose(): void;
+        private _draw;
+        private _drawCameraPredicate;
+        private _drawCameraBackground;
+        private _drawCameraForeground;
+        private _drawRenderTargetPredicate;
+        private _drawRenderTargetBackground;
+        private _drawRenderTargetForeground;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var layerPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var layerVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a full screen 2d layer.
+     * This can be useful to display a picture in the  background of your scene for instance.
+     * @see https://www.babylonjs-playground.com/#08A2BS#1
+     */
+    export class Layer {
+        /**
+         * Define the name of the layer.
+         */
+        name: string;
+        /**
+         * Define the texture the layer should display.
+         */
+        texture: Nullable<Texture>;
+        /**
+         * Is the layer in background or foreground.
+         */
+        isBackground: boolean;
+        /**
+         * Define the color of the layer (instead of texture).
+         */
+        color: Color4;
+        /**
+         * Define the scale of the layer in order to zoom in out of the texture.
+         */
+        scale: Vector2;
+        /**
+         * Define an offset for the layer in order to shift the texture.
+         */
+        offset: Vector2;
+        /**
+         * Define the alpha blending mode used in the layer in case the texture or color has an alpha.
+         */
+        alphaBlendingMode: number;
+        /**
+         * Define if the layer should alpha test or alpha blend with the rest of the scene.
+         * Alpha test will not mix with the background color in case of transparency.
+         * It will either use the texture color or the background depending on the alpha value of the current pixel.
+         */
+        alphaTest: boolean;
+        /**
+         * Define a mask to restrict the layer to only some of the scene cameras.
+         */
+        layerMask: number;
+        /**
+         * Define the list of render target the layer is visible into.
+         */
+        renderTargetTextures: RenderTargetTexture[];
+        /**
+         * Define if the layer is only used in renderTarget or if it also
+         * renders in the main frame buffer of the canvas.
+         */
+        renderOnlyInRenderTargetTextures: boolean;
+        private _scene;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _alphaTestEffect;
+        /**
+         * An event triggered when the layer is disposed.
+         */
+        onDisposeObservable: Observable<Layer>;
+        private _onDisposeObserver;
+        /**
+         * Back compatibility with callback before the onDisposeObservable existed.
+         * The set callback will be triggered when the layer has been disposed.
+         */
+        onDispose: () => void;
+        /**
+        * An event triggered before rendering the scene
+        */
+        onBeforeRenderObservable: Observable<Layer>;
+        private _onBeforeRenderObserver;
+        /**
+         * Back compatibility with callback before the onBeforeRenderObservable existed.
+         * The set callback will be triggered just before rendering the layer.
+         */
+        onBeforeRender: () => void;
+        /**
+        * An event triggered after rendering the scene
+        */
+        onAfterRenderObservable: Observable<Layer>;
+        private _onAfterRenderObserver;
+        /**
+         * Back compatibility with callback before the onAfterRenderObservable existed.
+         * The set callback will be triggered just after rendering the layer.
+         */
+        onAfterRender: () => void;
+        /**
+         * Instantiates a new layer.
+         * This represents a full screen 2d layer.
+         * This can be useful to display a picture in the  background of your scene for instance.
+         * @see https://www.babylonjs-playground.com/#08A2BS#1
+         * @param name Define the name of the layer in the scene
+         * @param imgUrl Define the url of the texture to display in the layer
+         * @param scene Define the scene the layer belongs to
+         * @param isBackground Defines whether the layer is displayed in front or behind the scene
+         * @param color Defines a color for the layer
+         */
+        constructor(
+        /**
+         * Define the name of the layer.
+         */
+        name: string, imgUrl: Nullable<string>, scene: Nullable<Scene>, isBackground?: boolean, color?: Color4);
+        private _createIndexBuffer;
+        /** @hidden */
+        _rebuild(): void;
+        /**
+         * Renders the layer in the scene.
+         */
+        render(): void;
+        /**
+         * Disposes and releases the associated ressources.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
     /** @hidden */
     export var lensFlarePixelShader: {
         name: string;
@@ -50488,7 +50546,9 @@ declare module BABYLON {
      * Defines a connection point for a block
      */
     export class NodeMaterialConnectionPoint {
+        /** @hidden */
         _ownerBlock: NodeMaterialBlock;
+        /** @hidden */
         _connectedPoint: Nullable<NodeMaterialConnectionPoint>;
         private _associatedVariableName;
         private _endpoints;
@@ -52155,6 +52215,7 @@ declare module BABYLON {
          * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
          * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
          * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+         * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
          * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
          * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
          * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -52186,6 +52247,7 @@ declare module BABYLON {
             updatable?: boolean;
             hasRings?: boolean;
             enclose?: boolean;
+            cap?: number;
             sideOrientation?: number;
             frontUVs?: Vector4;
             backUVs?: Vector4;

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


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


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
+ 507 - 383
dist/preview release/babylon.module.d.ts


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

@@ -2103,8 +2103,6 @@ declare module BABYLON.GUI {
         private _drawGradientSquare;
         private _drawCircle;
         private _createColorWheelCanvas;
-        private _RGBtoHSV;
-        private _HSVtoRGB;
         /** @hidden */
         _draw(context: CanvasRenderingContext2D): void;
         private _pointerIsDown;

+ 4 - 70
dist/preview release/gui/babylon.gui.js

@@ -1053,7 +1053,7 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
                     });
                     continue;
                 }
-                var position = mesh.getBoundingInfo ? mesh.getBoundingInfo().boundingSphere.center : mesh.getAbsolutePosition();
+                var position = mesh.getBoundingInfo ? mesh.getBoundingInfo().boundingSphere.center : babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Vector3"].ZeroReadOnly;
                 var projectedPosition = babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Project(position, mesh.getWorldMatrix(), scene.getTransformMatrix(), globalViewport);
                 if (projectedPosition.z < 0 || projectedPosition.z > 1) {
                     control.notRenderable = true;
@@ -1859,7 +1859,7 @@ var ColorPicker = /** @class */ (function (_super) {
                 return;
             }
             this._value.copyFrom(value);
-            this._RGBtoHSV(this._value, this._tmpColor);
+            this._value.toHSVToRef(this._tmpColor);
             this._h = this._tmpColor.r;
             this._s = Math.max(this._tmpColor.g, 0.00001);
             this._v = Math.max(this._tmpColor.b, 0.00001);
@@ -2004,7 +2004,7 @@ var ColorPicker = /** @class */ (function (_super) {
                 }
                 var dist = Math.sqrt(distSq);
                 var ang = Math.atan2(y, x);
-                this._HSVtoRGB(ang * 180 / Math.PI + 180, dist / radius, 1, color);
+                babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Color3"].HSVtoRGBToRef(ang * 180 / Math.PI + 180, dist / radius, 1, color);
                 var index = ((x + radius) + ((y + radius) * 2 * radius)) * 4;
                 data[index] = color.r * 255;
                 data[index + 1] = color.g * 255;
@@ -2040,72 +2040,6 @@ var ColorPicker = /** @class */ (function (_super) {
         context.putImageData(image, 0, 0);
         return canvas;
     };
-    ColorPicker.prototype._RGBtoHSV = function (color, result) {
-        var r = color.r;
-        var g = color.g;
-        var b = color.b;
-        var max = Math.max(r, g, b);
-        var min = Math.min(r, g, b);
-        var h = 0;
-        var s = 0;
-        var v = max;
-        var dm = max - min;
-        if (max !== 0) {
-            s = dm / max;
-        }
-        if (max != min) {
-            if (max == r) {
-                h = (g - b) / dm;
-                if (g < b) {
-                    h += 6;
-                }
-            }
-            else if (max == g) {
-                h = (b - r) / dm + 2;
-            }
-            else if (max == b) {
-                h = (r - g) / dm + 4;
-            }
-            h *= 60;
-        }
-        result.r = h;
-        result.g = s;
-        result.b = v;
-    };
-    ColorPicker.prototype._HSVtoRGB = function (hue, saturation, value, result) {
-        var chroma = value * saturation;
-        var h = hue / 60;
-        var x = chroma * (1 - Math.abs((h % 2) - 1));
-        var r = 0;
-        var g = 0;
-        var b = 0;
-        if (h >= 0 && h <= 1) {
-            r = chroma;
-            g = x;
-        }
-        else if (h >= 1 && h <= 2) {
-            r = x;
-            g = chroma;
-        }
-        else if (h >= 2 && h <= 3) {
-            g = chroma;
-            b = x;
-        }
-        else if (h >= 3 && h <= 4) {
-            g = x;
-            b = chroma;
-        }
-        else if (h >= 4 && h <= 5) {
-            r = x;
-            b = chroma;
-        }
-        else if (h >= 5 && h <= 6) {
-            r = chroma;
-            b = x;
-        }
-        var m = value - chroma;
-        result.set((r + m), (g + m), (b + m));
-    };
     /** @hidden */
     ColorPicker.prototype._draw = function (context) {
         context.save();
@@ -2157,7 +2091,7 @@ var ColorPicker = /** @class */ (function (_super) {
             this._v = Math.min(this._v, 1);
             this._v = Math.max(this._v, ColorPicker._Epsilon);
         }
-        this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
+        babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Color3"].HSVtoRGBToRef(this._h, this._s, this._v, this._tmpColor);
         this.value = this._tmpColor;
     };
     ColorPicker.prototype._isPointOnSquare = function (x, y) {

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


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


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

@@ -2178,8 +2178,6 @@ declare module "babylonjs-gui/2D/controls/colorpicker" {
         private _drawGradientSquare;
         private _drawCircle;
         private _createColorWheelCanvas;
-        private _RGBtoHSV;
-        private _HSVtoRGB;
         /** @hidden */
         _draw(context: CanvasRenderingContext2D): void;
         private _pointerIsDown;
@@ -5960,8 +5958,6 @@ declare module BABYLON.GUI {
         private _drawGradientSquare;
         private _drawCircle;
         private _createColorWheelCanvas;
-        private _RGBtoHSV;
-        private _HSVtoRGB;
         /** @hidden */
         _draw(context: CanvasRenderingContext2D): void;
         private _pointerIsDown;

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


+ 98 - 6
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -36856,6 +36856,15 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lines/checkBoxLineComponent */ "./components/actionTabs/lines/checkBoxLineComponent.tsx");
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
+/* harmony import */ var _lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/optionsLineComponent */ "./components/actionTabs/lines/optionsLineComponent.tsx");
+/* harmony import */ var babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! babylonjs/Lights/Shadows/shadowGenerator */ "babylonjs/Misc/observable");
+/* harmony import */ var babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__);
+/* harmony import */ var _lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../lines/sliderLineComponent */ "./components/actionTabs/lines/sliderLineComponent.tsx");
+/* harmony import */ var _lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../lines/buttonLineComponent */ "./components/actionTabs/lines/buttonLineComponent.tsx");
+
+
+
+
 
 
 
@@ -36866,12 +36875,71 @@ var CommonShadowLightPropertyGridComponent = /** @class */ (function (_super) {
     function CommonShadowLightPropertyGridComponent(props) {
         return _super.call(this, props) || this;
     }
+    CommonShadowLightPropertyGridComponent.prototype.createShadowGenerator = function () {
+        var light = this.props.light;
+        var scene = light.getScene();
+        var generator = new babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"](512, light);
+        scene.meshes.forEach(function (m) {
+            generator.addShadowCaster(m);
+            m.receiveShadows = true;
+        });
+        this.forceUpdate();
+    };
     CommonShadowLightPropertyGridComponent.prototype.render = function () {
+        var _this = this;
         var light = this.props.light;
-        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "SHADOWS" },
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Shadows enabled", target: light, propertyName: "shadowEnabled", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Shadows near plane", target: light, propertyName: "shadowMinZ", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Shadows far plane", target: light, propertyName: "shadowMaxZ", onPropertyChangedObservable: this.props.onPropertyChangedObservable })));
+        var generator = light.getShadowGenerator() || null;
+        var blurModeOptions = [
+            { label: "None", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_NONE },
+            { label: "PCF", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_PCF },
+            { label: "PCSS", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_PCSS },
+            { label: "Poisson", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_POISSONSAMPLING },
+            { label: "Exponential", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_EXPONENTIALSHADOWMAP },
+            { label: "Blurred exponential", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP },
+            { label: "Close exponential", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_CLOSEEXPONENTIALSHADOWMAP },
+            { label: "Blurred close exponential", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLURCLOSEEXPONENTIALSHADOWMAP },
+        ];
+        var filteringQualityOptions = [
+            { label: "Low", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].QUALITY_LOW },
+            { label: "Medium", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].QUALITY_MEDIUM },
+            { label: "High", value: babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].QUALITY_HIGH }
+        ];
+        var filter = generator ? generator.filter : 0;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", null,
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "SHADOWS" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Shadows enabled", target: light, propertyName: "shadowEnabled", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Shadows near plane", target: light, propertyName: "shadowMinZ", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Shadows far plane", target: light, propertyName: "shadowMaxZ", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+            generator == null &&
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "SHADOW GENERATOR" },
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_8__["ButtonLineComponent"], { label: "Create generator", onClick: function () { return _this.createShadowGenerator(); } })),
+            generator !== null &&
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "SHADOW GENERATOR" },
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Bias", target: generator, propertyName: "bias", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Normal bias", target: generator, propertyName: "normalBias", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Darkness", target: generator, minimum: 0, maximum: 1, step: 0.01, propertyName: "darkness", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Allow transparent shadows", target: generator, propertyName: "transparencyShadow", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Filter", options: blurModeOptions, onSelect: function () {
+                            _this.forceUpdate();
+                        }, target: generator, propertyName: "filter", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_PCF || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_PCSS) &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Filtering quality", options: filteringQualityOptions, onSelect: function () {
+                                _this.forceUpdate();
+                            }, target: generator, propertyName: "filteringQuality", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_PCSS) &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Penumbra ratio", minimum: 0, maximum: 0.5, step: 0.001, target: generator, propertyName: "contactHardeningLightSizeUVRatio", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Use kernel blur", target: generator, propertyName: "useKernelBlur", onValueChanged: function () { return _this.forceUpdate(); }, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                        !generator.useKernelBlur &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Blur box offset", target: generator, propertyName: "blurBoxOffset", minimum: 1, maximum: 64, step: 1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                        generator.useKernelBlur &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Blur kernel", target: generator, propertyName: "blurKernel", minimum: 1, maximum: 64, step: 1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_EXPONENTIALSHADOWMAP) &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_4__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Depth scale", target: generator, propertyName: "depthScale", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                    (filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_BLUREXPONENTIALSHADOWMAP || filter === babylonjs_Lights_Shadows_shadowGenerator__WEBPACK_IMPORTED_MODULE_6__["ShadowGenerator"].FILTER_EXPONENTIALSHADOWMAP) &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_7__["SliderLineComponent"], { label: "Blur scale", target: generator, propertyName: "blurScale", minimum: 1, maximum: 4, step: 1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }))));
     };
     return CommonShadowLightPropertyGridComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -37840,6 +37908,16 @@ var TexturePropertyGridComponent = /** @class */ (function (_super) {
             { label: "Skybox", value: babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Texture"].SKYBOX_MODE },
             { label: "Spherical", value: babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Texture"].SPHERICAL_MODE },
         ];
+        var extension = "";
+        var url = texture.url;
+        if (url) {
+            for (var index = url.length - 1; index >= 0; index--) {
+                if (url[index] === ".") {
+                    break;
+                }
+                extension = url[index] + extension;
+            }
+        }
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "pane" },
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "PREVIEW" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textureLineComponent__WEBPACK_IMPORTED_MODULE_7__["TextureLineComponent"], { texture: texture, width: 256, height: 256, globalState: this.props.globalState }),
@@ -37848,6 +37926,8 @@ var TexturePropertyGridComponent = /** @class */ (function (_super) {
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "GENERAL" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Width", value: texture.getSize().width.toString() }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Height", value: texture.getSize().height.toString() }),
+                extension &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "File format", value: extension }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Unique ID", value: texture.uniqueId.toString() }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Class", value: texture.getClassName() }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_5__["TextLineComponent"], { label: "Has alpha", value: texture.hasAlpha ? "Yes" : "No" }),
@@ -38043,6 +38123,7 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
         var normalLines = babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["LinesBuilder"].CreateLineSystem("normalLines", { lines: lines }, scene);
         normalLines.color = color;
         normalLines.parent = mesh;
+        normalLines.reservedDataStore = { hidden: true };
         if (!mesh.reservedDataStore) {
             mesh.reservedDataStore = {};
         }
@@ -38927,6 +39008,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
 /* harmony import */ var _lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../lines/sliderLineComponent */ "./components/actionTabs/lines/sliderLineComponent.tsx");
 /* harmony import */ var _lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../lines/optionsLineComponent */ "./components/actionTabs/lines/optionsLineComponent.tsx");
+/* harmony import */ var _lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../lines/buttonLineComponent */ "./components/actionTabs/lines/buttonLineComponent.tsx");
+
 
 
 
@@ -39001,6 +39084,13 @@ var ScenePropertyGridComponent = /** @class */ (function (_super) {
         var physicsEngine = scene.getPhysicsEngine();
         physicsEngine.setTimeStep(newValue);
     };
+    ScenePropertyGridComponent.prototype.normalizeScene = function () {
+        var scene = this.props.scene;
+        scene.meshes.forEach(function (mesh) {
+            mesh.normalizeToUnitCube(true);
+            mesh.computeWorldMatrix(true);
+        });
+    };
     ScenePropertyGridComponent.prototype.render = function () {
         var _this = this;
         var scene = this.props.scene;
@@ -39053,7 +39143,9 @@ var ScenePropertyGridComponent = /** @class */ (function (_super) {
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_11__["FloatLineComponent"], { lockObject: this.props.lockObject, label: "Time step", target: dummy, propertyName: "timeStep", onChange: function (newValue) { return _this.updateTimeStep(newValue); }, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_10__["Vector3LineComponent"], { label: "Gravity", target: dummy, propertyName: "gravity", onChange: function (newValue) { return _this.updateGravity(newValue); }, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "COLLISIONS", closed: true },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_10__["Vector3LineComponent"], { label: "Gravity", target: scene, propertyName: "gravity", onPropertyChangedObservable: this.props.onPropertyChangedObservable }))));
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_10__["Vector3LineComponent"], { label: "Gravity", target: scene, propertyName: "gravity", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "SHADOWS", closed: true },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_14__["ButtonLineComponent"], { label: "Normalize scene", onClick: function () { return _this.normalizeScene(); } }))));
     };
     return ScenePropertyGridComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -41224,7 +41316,7 @@ var SceneExplorerComponent = /** @class */ (function (_super) {
         nodeContextMenus.push({
             label: "Add new directional light",
             action: function () {
-                var newDirectionalLight = new babylonjs_Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["DirectionalLight"]("directional light", new babylonjs_Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["Vector3"](1, -1, 1), scene);
+                var newDirectionalLight = new babylonjs_Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["DirectionalLight"]("directional light", new babylonjs_Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["Vector3"](-1, -1, -0.5), scene);
                 _this.props.globalState.onSelectionChangedObservable.notifyObservers(newDirectionalLight);
             }
         });

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


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

@@ -596,6 +596,16 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface IScenePropertyGridComponentProps {
         globalState: GlobalState;
         scene: BABYLON.Scene;
@@ -612,6 +622,7 @@ declare module INSPECTOR {
         updateEnvironmentTexture(file: File): void;
         updateGravity(newValue: BABYLON.Vector3): void;
         updateTimeStep(newValue: number): void;
+        normalizeScene(): void;
         render(): JSX.Element;
     }
 }
@@ -648,6 +659,7 @@ declare module INSPECTOR {
     }
     export class CommonShadowLightPropertyGridComponent extends React.Component<ICommonShadowLightPropertyGridComponentProps> {
         constructor(props: ICommonShadowLightPropertyGridComponentProps);
+        createShadowGenerator(): void;
         render(): JSX.Element;
     }
 }
@@ -835,16 +847,6 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
-    export interface IButtonLineComponentProps {
-        label: string;
-        onClick: () => void;
-    }
-    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
-        constructor(props: IButtonLineComponentProps);
-        render(): JSX.Element;
-    }
-}
-declare module INSPECTOR {
     interface IAnimationGroupGridComponentProps {
         globalState: GlobalState;
         animationGroup: BABYLON.AnimationGroup;
@@ -1712,7 +1714,7 @@ declare module INSPECTOR {
         private static _CreateSceneExplorer;
         private static _CreateActionTabs;
         private static _CreateEmbedHost;
-        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): BABYLON.Nullable<HTMLDivElement>;
         static readonly IsVisible: boolean;
         static EarlyAttachToLoader(): void;
         static Show(scene: BABYLON.Scene, userOptions: Partial<BABYLON.IInspectorOptions>): void;

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

@@ -706,6 +706,17 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/fog
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/actionTabs/lines/buttonLineComponent" {
+    import * as React from "react";
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent" {
     import * as React from "react";
     import { Observable } from "babylonjs/Misc/observable";
@@ -730,6 +741,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/sce
         updateEnvironmentTexture(file: File): void;
         updateGravity(newValue: Vector3): void;
         updateTimeStep(newValue: number): void;
+        normalizeScene(): void;
         render(): JSX.Element;
     }
 }
@@ -784,6 +796,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lig
     }
     export class CommonShadowLightPropertyGridComponent extends React.Component<ICommonShadowLightPropertyGridComponentProps> {
         constructor(props: ICommonShadowLightPropertyGridComponentProps);
+        createShadowGenerator(): void;
         render(): JSX.Element;
     }
 }
@@ -1046,17 +1059,6 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/gui
         render(): JSX.Element;
     }
 }
-declare module "babylonjs-inspector/components/actionTabs/lines/buttonLineComponent" {
-    import * as React from "react";
-    export interface IButtonLineComponentProps {
-        label: string;
-        onClick: () => void;
-    }
-    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
-        constructor(props: IButtonLineComponentProps);
-        render(): JSX.Element;
-    }
-}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/animationGroupPropertyGridComponent" {
     import * as React from "react";
     import { Observable } from "babylonjs/Misc/observable";
@@ -2151,6 +2153,7 @@ declare module "babylonjs-inspector/components/embedHost/embedHostComponent" {
 }
 declare module "babylonjs-inspector/inspector" {
     import { IInspectorOptions } from "babylonjs/Debug/debugLayer";
+    import { Nullable } from "babylonjs/types";
     import { Observable } from "babylonjs/Misc/observable";
     import { Scene } from "babylonjs/scene";
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
@@ -2173,7 +2176,7 @@ declare module "babylonjs-inspector/inspector" {
         private static _CreateSceneExplorer;
         private static _CreateActionTabs;
         private static _CreateEmbedHost;
-        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): Nullable<HTMLDivElement>;
         static readonly IsVisible: boolean;
         static EarlyAttachToLoader(): void;
         static Show(scene: Scene, userOptions: Partial<IInspectorOptions>): void;
@@ -2791,6 +2794,16 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface IScenePropertyGridComponentProps {
         globalState: GlobalState;
         scene: BABYLON.Scene;
@@ -2807,6 +2820,7 @@ declare module INSPECTOR {
         updateEnvironmentTexture(file: File): void;
         updateGravity(newValue: BABYLON.Vector3): void;
         updateTimeStep(newValue: number): void;
+        normalizeScene(): void;
         render(): JSX.Element;
     }
 }
@@ -2843,6 +2857,7 @@ declare module INSPECTOR {
     }
     export class CommonShadowLightPropertyGridComponent extends React.Component<ICommonShadowLightPropertyGridComponentProps> {
         constructor(props: ICommonShadowLightPropertyGridComponentProps);
+        createShadowGenerator(): void;
         render(): JSX.Element;
     }
 }
@@ -3030,16 +3045,6 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
-    export interface IButtonLineComponentProps {
-        label: string;
-        onClick: () => void;
-    }
-    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
-        constructor(props: IButtonLineComponentProps);
-        render(): JSX.Element;
-    }
-}
-declare module INSPECTOR {
     interface IAnimationGroupGridComponentProps {
         globalState: GlobalState;
         animationGroup: BABYLON.AnimationGroup;
@@ -3907,7 +3912,7 @@ declare module INSPECTOR {
         private static _CreateSceneExplorer;
         private static _CreateActionTabs;
         private static _CreateEmbedHost;
-        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        static _CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): BABYLON.Nullable<HTMLDivElement>;
         static readonly IsVisible: boolean;
         static EarlyAttachToLoader(): void;
         static Show(scene: BABYLON.Scene, userOptions: Partial<BABYLON.IInspectorOptions>): void;

+ 319 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts

@@ -1,6 +1,291 @@
 /// <reference types="react" />
 declare module NODEEDITOR {
     export class GlobalState {
+        nodeMaterial?: BABYLON.NodeMaterial;
+        hostDocument?: BABYLON.Nullable<Document>;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Port model for the generic node
+     */
+    export class GenericPortModel extends PortModel {
+        /**
+         * If the port is input or output
+         */
+        position: string | "input" | "output";
+        /**
+         * What the port is connected to
+         */
+        connection: BABYLON.Nullable<BABYLON.NodeMaterialConnectionPoint>;
+        static idCounter: number;
+        constructor(name: string, type?: string);
+        syncWithNodeMaterialConnectionPoint(connection: BABYLON.NodeMaterialConnectionPoint): void;
+        getNodeModel(): GenericNodeModel;
+        link(outPort: GenericPortModel): LinkModel<import("storm-react-diagrams").LinkModelListener>;
+        getInputFromBlock(): void;
+        createLinkModel(): LinkModel;
+        getValue: Function;
+        static SortInputOutput(a: BABYLON.Nullable<GenericPortModel>, b: BABYLON.Nullable<GenericPortModel>): {
+            input: GenericPortModel;
+            output: GenericPortModel;
+        } | null;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Generic node model which stores information about a node editor block
+     */
+    export class GenericNodeModel extends NodeModel {
+        /**
+         * The babylon block this node represents
+         */
+        block: BABYLON.Nullable<BABYLON.NodeMaterialBlock>;
+        /**
+         * Labels for the block
+         */
+        headerLabels: Array<{
+            text: string;
+        }>;
+        /**
+         * BABYLON.Texture for the node if it exists
+         */
+        texture: BABYLON.Nullable<BABYLON.Texture>;
+        /**
+         * BABYLON.Vector2 for the node if it exists
+         */
+        vector2: BABYLON.Nullable<BABYLON.Vector2>;
+        /**
+         * BABYLON.Vector3 for the node if it exists
+         */
+        vector3: BABYLON.Nullable<BABYLON.Vector3>;
+        /**
+         * BABYLON.Vector4 for the node if it exists
+         */
+        vector4: BABYLON.Nullable<BABYLON.Vector4>;
+        /**
+         * BABYLON.Matrix for the node if it exists
+         */
+        matrix: BABYLON.Nullable<BABYLON.Matrix>;
+        ports: {
+            [s: string]: GenericPortModel;
+        };
+        /**
+         * Constructs the node model
+         */
+        constructor();
+    }
+}
+declare module NODEEDITOR {
+    interface ITextureLineComponentProps {
+        texture: BABYLON.BaseTexture;
+        width: number;
+        height: number;
+        globalState?: any;
+        hideChannelSelect?: boolean;
+    }
+    export class TextureLineComponent extends React.Component<ITextureLineComponentProps, {
+        displayRed: boolean;
+        displayGreen: boolean;
+        displayBlue: boolean;
+        displayAlpha: boolean;
+        face: number;
+    }> {
+        constructor(props: ITextureLineComponentProps);
+        shouldComponentUpdate(nextProps: ITextureLineComponentProps, nextState: {
+            displayRed: boolean;
+            displayGreen: boolean;
+            displayBlue: boolean;
+            displayAlpha: boolean;
+            face: number;
+        }): boolean;
+        componentDidMount(): void;
+        componentDidUpdate(): void;
+        updatePreview(): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface IFileButtonLineComponentProps {
+        label: string;
+        onClick: (file: File) => void;
+        accept: string;
+    }
+    export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
+        constructor(props: IFileButtonLineComponentProps);
+        onChange(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface INumericInputComponentProps {
+        label: string;
+        value: number;
+        step?: number;
+        onChange: (value: number) => void;
+    }
+    export class NumericInputComponent extends React.Component<INumericInputComponentProps, {
+        value: string;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: INumericInputComponentProps);
+        shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: {
+            value: string;
+        }): boolean;
+        updateValue(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    export class PropertyChangedEvent {
+        object: any;
+        property: string;
+        value: any;
+        initialValue: any;
+    }
+}
+declare module NODEEDITOR {
+    interface IVector2LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: BABYLON.Vector2) => void;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, {
+        isExpanded: boolean;
+        value: BABYLON.Vector2;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector2LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: BABYLON.Vector2;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: BABYLON.Vector2): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface IVector3LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: BABYLON.Vector3) => void;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class Vector3LineComponent extends React.Component<IVector3LineComponentProps, {
+        isExpanded: boolean;
+        value: BABYLON.Vector3;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector3LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector3LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: BABYLON.Vector3;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: BABYLON.Vector3): void;
+        updateVector3(): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        updateStateZ(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * GenericNodeWidgetProps
+     */
+    export interface GenericNodeWidgetProps {
+        node: BABYLON.Nullable<GenericNodeModel>;
+    }
+    /**
+     * GenericNodeWidgetState
+     */
+    export interface GenericNodeWidgetState {
+    }
+    /**
+     * Used to display a node block for the node editor
+     */
+    export class GenericNodeWidget extends React.Component<GenericNodeWidgetProps, GenericNodeWidgetState> {
+        /**
+         * Creates a GenericNodeWidget
+         * @param props
+         */
+        constructor(props: GenericNodeWidgetProps);
+        /**
+         * Replaces the texture of the node
+         * @param file the file of the texture to use
+         */
+        replaceTexture(file: File): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Node factory which creates editor nodes
+     */
+    export class GenericNodeFactory extends SRD.AbstractNodeFactory {
+        /**
+         * Constructs a GenericNodeFactory
+         */
+        constructor();
+        /**
+         * Generates a node widget
+         * @param diagramEngine diagram engine
+         * @param node node to generate
+         * @returns node widget jsx
+         */
+        generateReactWidget(diagramEngine: SRD.DiagramEngine, node: GenericNodeModel): JSX.Element;
+        /**
+         * Gets a new instance of a node model
+         * @returns generic node model
+         */
+        getNewInstance(): GenericNodeModel;
+    }
+}
+declare module NODEEDITOR {
+    interface ILineContainerComponentProps {
+        globalState?: any;
+        title: string;
+        children: any[] | any;
+        closed?: boolean;
+    }
+    export class LineContainerComponent extends React.Component<ILineContainerComponentProps, {
+        isExpanded: boolean;
+        isHighlighted: boolean;
+    }> {
+        private static _InMemoryStorage;
+        constructor(props: ILineContainerComponentProps);
+        switchExpandedState(): void;
+        componentDidMount(): void;
+        renderHeader(): JSX.Element;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
     }
 }
 declare module NODEEDITOR {
@@ -8,11 +293,43 @@ declare module NODEEDITOR {
         globalState: GlobalState;
     }
     export class GraphEditor extends React.Component<IGraphEditorProps> {
+        private _engine;
+        private _model;
+        private _nodes;
+        /**
+         * Current row/column position used when adding new nodes
+         */
+        private _rowPos;
+        /**
+         * Creates a node and recursivly creates its parent nodes from it's input
+         * @param nodeMaterialBlock
+         */
+        createNodeFromObject(options: {
+            column: number;
+            nodeMaterialBlock?: BABYLON.NodeMaterialBlock;
+        }): GenericNodeModel;
+        componentDidMount(): void;
+        componentWillUnmount(): void;
         constructor(props: IGraphEditorProps);
+        addNodeFromClass(ObjectClass: typeof BABYLON.NodeMaterialBlock): GenericNodeModel;
+        addValueNode(type: string, column?: number, connection?: BABYLON.NodeMaterialConnectionPoint): GenericNodeModel;
+        allBlocks: {
+            Fragment: (typeof BABYLON.AlphaTestBlock | typeof BABYLON.FragmentOutputBlock | typeof BABYLON.ImageProcessingBlock | typeof BABYLON.RGBAMergerBlock | typeof BABYLON.RGBASplitterBlock | typeof BABYLON.TextureBlock)[];
+            Vertex: (typeof BABYLON.BonesBlock | typeof BABYLON.InstancesBlock | typeof BABYLON.MorphTargetsBlock | typeof BABYLON.VertexOutputBlock)[];
+            Dual: (typeof BABYLON.FogBlock)[];
+            Other: (typeof BABYLON.AddBlock | typeof BABYLON.ClampBlock | typeof BABYLON.MatrixMultiplicationBlock | typeof BABYLON.MultiplyBlock | typeof BABYLON.Vector2TransformBlock | typeof BABYLON.Vector3TransformBlock | typeof BABYLON.Vector4TransformBlock)[];
+            Value: string[];
+        };
         render(): JSX.Element;
     }
 }
 declare module NODEEDITOR {
+    export class Popup {
+        static CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        private static _CopyStyles;
+    }
+}
+declare module NODEEDITOR {
     /**
      * Interface used to specify creation options for the node editor
      */
@@ -20,7 +337,8 @@ declare module NODEEDITOR {
         /**
          * Defines the DOM element that will host the node editor
          */
-        hostElement: HTMLDivElement;
+        hostElement?: HTMLDivElement;
+        nodeMaterial?: BABYLON.NodeMaterial;
     }
     /**
      * Class used to create a node editor

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


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


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


+ 691 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts

@@ -1,20 +1,390 @@
 /// <reference types="react" />
 declare module "babylonjs-nodeEditor/globalState" {
+    import { NodeMaterial } from "babylonjs/Materials/Node/nodeMaterial";
+    import { Nullable } from "babylonjs/types";
     export class GlobalState {
+        nodeMaterial?: NodeMaterial;
+        hostDocument?: Nullable<Document>;
+    }
+}
+declare module "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericPortModel" {
+    import { LinkModel, PortModel } from "storm-react-diagrams";
+    import { Nullable } from 'babylonjs/types';
+    import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
+    import { GenericNodeModel } from "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeModel";
+    /**
+     * Port model for the generic node
+     */
+    export class GenericPortModel extends PortModel {
+        /**
+         * If the port is input or output
+         */
+        position: string | "input" | "output";
+        /**
+         * What the port is connected to
+         */
+        connection: Nullable<NodeMaterialConnectionPoint>;
+        static idCounter: number;
+        constructor(name: string, type?: string);
+        syncWithNodeMaterialConnectionPoint(connection: NodeMaterialConnectionPoint): void;
+        getNodeModel(): GenericNodeModel;
+        link(outPort: GenericPortModel): LinkModel<import("storm-react-diagrams").LinkModelListener>;
+        getInputFromBlock(): void;
+        createLinkModel(): LinkModel;
+        getValue: Function;
+        static SortInputOutput(a: Nullable<GenericPortModel>, b: Nullable<GenericPortModel>): {
+            input: GenericPortModel;
+            output: GenericPortModel;
+        } | null;
+    }
+}
+declare module "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeModel" {
+    import { NodeModel } from "storm-react-diagrams";
+    import { Nullable } from 'babylonjs/types';
+    import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+    import { Texture } from 'babylonjs/Materials/Textures/texture';
+    import { Vector2, Vector3, Vector4, Matrix } from 'babylonjs/Maths/math';
+    import { GenericPortModel } from "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericPortModel";
+    /**
+     * Generic node model which stores information about a node editor block
+     */
+    export class GenericNodeModel extends NodeModel {
+        /**
+         * The babylon block this node represents
+         */
+        block: Nullable<NodeMaterialBlock>;
+        /**
+         * Labels for the block
+         */
+        headerLabels: Array<{
+            text: string;
+        }>;
+        /**
+         * Texture for the node if it exists
+         */
+        texture: Nullable<Texture>;
+        /**
+         * Vector2 for the node if it exists
+         */
+        vector2: Nullable<Vector2>;
+        /**
+         * Vector3 for the node if it exists
+         */
+        vector3: Nullable<Vector3>;
+        /**
+         * Vector4 for the node if it exists
+         */
+        vector4: Nullable<Vector4>;
+        /**
+         * Matrix for the node if it exists
+         */
+        matrix: Nullable<Matrix>;
+        ports: {
+            [s: string]: GenericPortModel;
+        };
+        /**
+         * Constructs the node model
+         */
+        constructor();
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/textureLineComponent" {
+    import * as React from "react";
+    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+    interface ITextureLineComponentProps {
+        texture: BaseTexture;
+        width: number;
+        height: number;
+        globalState?: any;
+        hideChannelSelect?: boolean;
+    }
+    export class TextureLineComponent extends React.Component<ITextureLineComponentProps, {
+        displayRed: boolean;
+        displayGreen: boolean;
+        displayBlue: boolean;
+        displayAlpha: boolean;
+        face: number;
+    }> {
+        constructor(props: ITextureLineComponentProps);
+        shouldComponentUpdate(nextProps: ITextureLineComponentProps, nextState: {
+            displayRed: boolean;
+            displayGreen: boolean;
+            displayBlue: boolean;
+            displayAlpha: boolean;
+            face: number;
+        }): boolean;
+        componentDidMount(): void;
+        componentDidUpdate(): void;
+        updatePreview(): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/fileButtonLineComponent" {
+    import * as React from "react";
+    interface IFileButtonLineComponentProps {
+        label: string;
+        onClick: (file: File) => void;
+        accept: string;
+    }
+    export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
+        constructor(props: IFileButtonLineComponentProps);
+        onChange(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/numericInputComponent" {
+    import * as React from "react";
+    interface INumericInputComponentProps {
+        label: string;
+        value: number;
+        step?: number;
+        onChange: (value: number) => void;
+    }
+    export class NumericInputComponent extends React.Component<INumericInputComponentProps, {
+        value: string;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: INumericInputComponentProps);
+        shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: {
+            value: string;
+        }): boolean;
+        updateValue(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/propertyChangedEvent" {
+    export class PropertyChangedEvent {
+        object: any;
+        property: string;
+        value: any;
+        initialValue: any;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/vector2LineComponent" {
+    import * as React from "react";
+    import { Vector2 } from "babylonjs/Maths/math";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-nodeEditor/sharedComponents/propertyChangedEvent";
+    interface IVector2LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: Vector2) => void;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    }
+    export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, {
+        isExpanded: boolean;
+        value: Vector2;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector2LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: Vector2;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: Vector2): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/vector3LineComponent" {
+    import * as React from "react";
+    import { Vector3 } from "babylonjs/Maths/math";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-nodeEditor/sharedComponents/propertyChangedEvent";
+    interface IVector3LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: Vector3) => void;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    }
+    export class Vector3LineComponent extends React.Component<IVector3LineComponentProps, {
+        isExpanded: boolean;
+        value: Vector3;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector3LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector3LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: Vector3;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: Vector3): void;
+        updateVector3(): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        updateStateZ(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeWidget" {
+    import * as React from "react";
+    import { GenericNodeModel } from "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeModel";
+    import { Nullable } from 'babylonjs/types';
+    /**
+     * GenericNodeWidgetProps
+     */
+    export interface GenericNodeWidgetProps {
+        node: Nullable<GenericNodeModel>;
+    }
+    /**
+     * GenericNodeWidgetState
+     */
+    export interface GenericNodeWidgetState {
+    }
+    /**
+     * Used to display a node block for the node editor
+     */
+    export class GenericNodeWidget extends React.Component<GenericNodeWidgetProps, GenericNodeWidgetState> {
+        /**
+         * Creates a GenericNodeWidget
+         * @param props
+         */
+        constructor(props: GenericNodeWidgetProps);
+        /**
+         * Replaces the texture of the node
+         * @param file the file of the texture to use
+         */
+        replaceTexture(file: File): void;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeFactory" {
+    import * as SRD from "storm-react-diagrams";
+    import { GenericNodeModel } from "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeModel";
+    /**
+     * Node factory which creates editor nodes
+     */
+    export class GenericNodeFactory extends SRD.AbstractNodeFactory {
+        /**
+         * Constructs a GenericNodeFactory
+         */
+        constructor();
+        /**
+         * Generates a node widget
+         * @param diagramEngine diagram engine
+         * @param node node to generate
+         * @returns node widget jsx
+         */
+        generateReactWidget(diagramEngine: SRD.DiagramEngine, node: GenericNodeModel): JSX.Element;
+        /**
+         * Gets a new instance of a node model
+         * @returns generic node model
+         */
+        getNewInstance(): GenericNodeModel;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/lineContainerComponent" {
+    import * as React from "react";
+    interface ILineContainerComponentProps {
+        globalState?: any;
+        title: string;
+        children: any[] | any;
+        closed?: boolean;
+    }
+    export class LineContainerComponent extends React.Component<ILineContainerComponentProps, {
+        isExpanded: boolean;
+        isHighlighted: boolean;
+    }> {
+        private static _InMemoryStorage;
+        constructor(props: ILineContainerComponentProps);
+        switchExpandedState(): void;
+        componentDidMount(): void;
+        renderHeader(): JSX.Element;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-nodeEditor/sharedComponents/buttonLineComponent" {
+    import * as React from "react";
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
     }
 }
 declare module "babylonjs-nodeEditor/components/graphEditor" {
     import * as React from "react";
     import { GlobalState } from "babylonjs-nodeEditor/globalState";
+    import { GenericNodeModel } from "babylonjs-nodeEditor/components/customDiragramNodes/generic/genericNodeModel";
+    import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+    import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
+    import { AlphaTestBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/alphaTestBlock';
+    import { FragmentOutputBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/fragmentOutputBlock';
+    import { ImageProcessingBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/imageProcessingBlock';
+    import { RGBAMergerBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbaMergerBlock';
+    import { RGBASplitterBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbaSplitterBlock';
+    import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/textureBlock';
+    import { BonesBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/bonesBlock';
+    import { InstancesBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/instancesBlock';
+    import { MorphTargetsBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/morphTargetsBlock';
+    import { VertexOutputBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/vertexOutputBlock';
+    import { FogBlock } from 'babylonjs/Materials/Node/Blocks/Dual/fogBlock';
+    import { AddBlock } from 'babylonjs/Materials/Node/Blocks/addBlock';
+    import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
+    import { MatrixMultiplicationBlock } from 'babylonjs/Materials/Node/Blocks/matrixMultiplicationBlock';
+    import { MultiplyBlock } from 'babylonjs/Materials/Node/Blocks/multiplyBlock';
+    import { Vector2TransformBlock } from 'babylonjs/Materials/Node/Blocks/vector2TransformBlock';
+    import { Vector3TransformBlock } from 'babylonjs/Materials/Node/Blocks/vector3TransformBlock';
+    import { Vector4TransformBlock } from 'babylonjs/Materials/Node/Blocks/vector4TransformBlock';
     interface IGraphEditorProps {
         globalState: GlobalState;
     }
     export class GraphEditor extends React.Component<IGraphEditorProps> {
+        private _engine;
+        private _model;
+        private _nodes;
+        /**
+         * Current row/column position used when adding new nodes
+         */
+        private _rowPos;
+        /**
+         * Creates a node and recursivly creates its parent nodes from it's input
+         * @param nodeMaterialBlock
+         */
+        createNodeFromObject(options: {
+            column: number;
+            nodeMaterialBlock?: NodeMaterialBlock;
+        }): GenericNodeModel;
+        componentDidMount(): void;
+        componentWillUnmount(): void;
         constructor(props: IGraphEditorProps);
+        addNodeFromClass(ObjectClass: typeof NodeMaterialBlock): GenericNodeModel;
+        addValueNode(type: string, column?: number, connection?: NodeMaterialConnectionPoint): GenericNodeModel;
+        allBlocks: {
+            Fragment: (typeof AlphaTestBlock | typeof FragmentOutputBlock | typeof ImageProcessingBlock | typeof RGBAMergerBlock | typeof RGBASplitterBlock | typeof TextureBlock)[];
+            Vertex: (typeof BonesBlock | typeof InstancesBlock | typeof MorphTargetsBlock | typeof VertexOutputBlock)[];
+            Dual: (typeof FogBlock)[];
+            Other: (typeof AddBlock | typeof ClampBlock | typeof MatrixMultiplicationBlock | typeof MultiplyBlock | typeof Vector2TransformBlock | typeof Vector3TransformBlock | typeof Vector4TransformBlock)[];
+            Value: string[];
+        };
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-nodeEditor/sharedComponents/popup" {
+    export class Popup {
+        static CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        private static _CopyStyles;
+    }
+}
 declare module "babylonjs-nodeEditor/nodeEditor" {
+    import { NodeMaterial } from "babylonjs/Materials/Node/nodeMaterial";
     /**
      * Interface used to specify creation options for the node editor
      */
@@ -22,7 +392,8 @@ declare module "babylonjs-nodeEditor/nodeEditor" {
         /**
          * Defines the DOM element that will host the node editor
          */
-        hostElement: HTMLDivElement;
+        hostElement?: HTMLDivElement;
+        nodeMaterial?: NodeMaterial;
     }
     /**
      * Class used to create a node editor
@@ -47,6 +418,291 @@ declare module "babylonjs-nodeEditor" {
 /// <reference types="react" />
 declare module NODEEDITOR {
     export class GlobalState {
+        nodeMaterial?: BABYLON.NodeMaterial;
+        hostDocument?: BABYLON.Nullable<Document>;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Port model for the generic node
+     */
+    export class GenericPortModel extends PortModel {
+        /**
+         * If the port is input or output
+         */
+        position: string | "input" | "output";
+        /**
+         * What the port is connected to
+         */
+        connection: BABYLON.Nullable<BABYLON.NodeMaterialConnectionPoint>;
+        static idCounter: number;
+        constructor(name: string, type?: string);
+        syncWithNodeMaterialConnectionPoint(connection: BABYLON.NodeMaterialConnectionPoint): void;
+        getNodeModel(): GenericNodeModel;
+        link(outPort: GenericPortModel): LinkModel<import("storm-react-diagrams").LinkModelListener>;
+        getInputFromBlock(): void;
+        createLinkModel(): LinkModel;
+        getValue: Function;
+        static SortInputOutput(a: BABYLON.Nullable<GenericPortModel>, b: BABYLON.Nullable<GenericPortModel>): {
+            input: GenericPortModel;
+            output: GenericPortModel;
+        } | null;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Generic node model which stores information about a node editor block
+     */
+    export class GenericNodeModel extends NodeModel {
+        /**
+         * The babylon block this node represents
+         */
+        block: BABYLON.Nullable<BABYLON.NodeMaterialBlock>;
+        /**
+         * Labels for the block
+         */
+        headerLabels: Array<{
+            text: string;
+        }>;
+        /**
+         * BABYLON.Texture for the node if it exists
+         */
+        texture: BABYLON.Nullable<BABYLON.Texture>;
+        /**
+         * BABYLON.Vector2 for the node if it exists
+         */
+        vector2: BABYLON.Nullable<BABYLON.Vector2>;
+        /**
+         * BABYLON.Vector3 for the node if it exists
+         */
+        vector3: BABYLON.Nullable<BABYLON.Vector3>;
+        /**
+         * BABYLON.Vector4 for the node if it exists
+         */
+        vector4: BABYLON.Nullable<BABYLON.Vector4>;
+        /**
+         * BABYLON.Matrix for the node if it exists
+         */
+        matrix: BABYLON.Nullable<BABYLON.Matrix>;
+        ports: {
+            [s: string]: GenericPortModel;
+        };
+        /**
+         * Constructs the node model
+         */
+        constructor();
+    }
+}
+declare module NODEEDITOR {
+    interface ITextureLineComponentProps {
+        texture: BABYLON.BaseTexture;
+        width: number;
+        height: number;
+        globalState?: any;
+        hideChannelSelect?: boolean;
+    }
+    export class TextureLineComponent extends React.Component<ITextureLineComponentProps, {
+        displayRed: boolean;
+        displayGreen: boolean;
+        displayBlue: boolean;
+        displayAlpha: boolean;
+        face: number;
+    }> {
+        constructor(props: ITextureLineComponentProps);
+        shouldComponentUpdate(nextProps: ITextureLineComponentProps, nextState: {
+            displayRed: boolean;
+            displayGreen: boolean;
+            displayBlue: boolean;
+            displayAlpha: boolean;
+            face: number;
+        }): boolean;
+        componentDidMount(): void;
+        componentDidUpdate(): void;
+        updatePreview(): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface IFileButtonLineComponentProps {
+        label: string;
+        onClick: (file: File) => void;
+        accept: string;
+    }
+    export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
+        constructor(props: IFileButtonLineComponentProps);
+        onChange(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface INumericInputComponentProps {
+        label: string;
+        value: number;
+        step?: number;
+        onChange: (value: number) => void;
+    }
+    export class NumericInputComponent extends React.Component<INumericInputComponentProps, {
+        value: string;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: INumericInputComponentProps);
+        shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: {
+            value: string;
+        }): boolean;
+        updateValue(evt: any): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    export class PropertyChangedEvent {
+        object: any;
+        property: string;
+        value: any;
+        initialValue: any;
+    }
+}
+declare module NODEEDITOR {
+    interface IVector2LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: BABYLON.Vector2) => void;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, {
+        isExpanded: boolean;
+        value: BABYLON.Vector2;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector2LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: BABYLON.Vector2;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: BABYLON.Vector2): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface IVector3LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        step?: number;
+        onChange?: (newvalue: BABYLON.Vector3) => void;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class Vector3LineComponent extends React.Component<IVector3LineComponentProps, {
+        isExpanded: boolean;
+        value: BABYLON.Vector3;
+    }> {
+        static defaultProps: {
+            step: number;
+        };
+        private _localChange;
+        constructor(props: IVector3LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector3LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: BABYLON.Vector3;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: BABYLON.Vector3): void;
+        updateVector3(): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        updateStateZ(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * GenericNodeWidgetProps
+     */
+    export interface GenericNodeWidgetProps {
+        node: BABYLON.Nullable<GenericNodeModel>;
+    }
+    /**
+     * GenericNodeWidgetState
+     */
+    export interface GenericNodeWidgetState {
+    }
+    /**
+     * Used to display a node block for the node editor
+     */
+    export class GenericNodeWidget extends React.Component<GenericNodeWidgetProps, GenericNodeWidgetState> {
+        /**
+         * Creates a GenericNodeWidget
+         * @param props
+         */
+        constructor(props: GenericNodeWidgetProps);
+        /**
+         * Replaces the texture of the node
+         * @param file the file of the texture to use
+         */
+        replaceTexture(file: File): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    /**
+     * Node factory which creates editor nodes
+     */
+    export class GenericNodeFactory extends SRD.AbstractNodeFactory {
+        /**
+         * Constructs a GenericNodeFactory
+         */
+        constructor();
+        /**
+         * Generates a node widget
+         * @param diagramEngine diagram engine
+         * @param node node to generate
+         * @returns node widget jsx
+         */
+        generateReactWidget(diagramEngine: SRD.DiagramEngine, node: GenericNodeModel): JSX.Element;
+        /**
+         * Gets a new instance of a node model
+         * @returns generic node model
+         */
+        getNewInstance(): GenericNodeModel;
+    }
+}
+declare module NODEEDITOR {
+    interface ILineContainerComponentProps {
+        globalState?: any;
+        title: string;
+        children: any[] | any;
+        closed?: boolean;
+    }
+    export class LineContainerComponent extends React.Component<ILineContainerComponentProps, {
+        isExpanded: boolean;
+        isHighlighted: boolean;
+    }> {
+        private static _InMemoryStorage;
+        constructor(props: ILineContainerComponentProps);
+        switchExpandedState(): void;
+        componentDidMount(): void;
+        renderHeader(): JSX.Element;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    export interface IButtonLineComponentProps {
+        label: string;
+        onClick: () => void;
+    }
+    export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+        constructor(props: IButtonLineComponentProps);
+        render(): JSX.Element;
     }
 }
 declare module NODEEDITOR {
@@ -54,11 +710,43 @@ declare module NODEEDITOR {
         globalState: GlobalState;
     }
     export class GraphEditor extends React.Component<IGraphEditorProps> {
+        private _engine;
+        private _model;
+        private _nodes;
+        /**
+         * Current row/column position used when adding new nodes
+         */
+        private _rowPos;
+        /**
+         * Creates a node and recursivly creates its parent nodes from it's input
+         * @param nodeMaterialBlock
+         */
+        createNodeFromObject(options: {
+            column: number;
+            nodeMaterialBlock?: BABYLON.NodeMaterialBlock;
+        }): GenericNodeModel;
+        componentDidMount(): void;
+        componentWillUnmount(): void;
         constructor(props: IGraphEditorProps);
+        addNodeFromClass(ObjectClass: typeof BABYLON.NodeMaterialBlock): GenericNodeModel;
+        addValueNode(type: string, column?: number, connection?: BABYLON.NodeMaterialConnectionPoint): GenericNodeModel;
+        allBlocks: {
+            Fragment: (typeof BABYLON.AlphaTestBlock | typeof BABYLON.FragmentOutputBlock | typeof BABYLON.ImageProcessingBlock | typeof BABYLON.RGBAMergerBlock | typeof BABYLON.RGBASplitterBlock | typeof BABYLON.TextureBlock)[];
+            Vertex: (typeof BABYLON.BonesBlock | typeof BABYLON.InstancesBlock | typeof BABYLON.MorphTargetsBlock | typeof BABYLON.VertexOutputBlock)[];
+            Dual: (typeof BABYLON.FogBlock)[];
+            Other: (typeof BABYLON.AddBlock | typeof BABYLON.ClampBlock | typeof BABYLON.MatrixMultiplicationBlock | typeof BABYLON.MultiplyBlock | typeof BABYLON.Vector2TransformBlock | typeof BABYLON.Vector3TransformBlock | typeof BABYLON.Vector4TransformBlock)[];
+            Value: string[];
+        };
         render(): JSX.Element;
     }
 }
 declare module NODEEDITOR {
+    export class Popup {
+        static CreatePopup(title: string, windowVariableName: string, width?: number, height?: number): HTMLDivElement | null;
+        private static _CopyStyles;
+    }
+}
+declare module NODEEDITOR {
     /**
      * Interface used to specify creation options for the node editor
      */
@@ -66,7 +754,8 @@ declare module NODEEDITOR {
         /**
          * Defines the DOM element that will host the node editor
          */
-        hostElement: HTMLDivElement;
+        hostElement?: HTMLDivElement;
+        nodeMaterial?: BABYLON.NodeMaterial;
     }
     /**
      * Class used to create a node editor

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

@@ -1 +1 @@
-{"engineOnly":290149,"sceneOnly":499910,"minGridMaterial":626892,"minStandardMaterial":751651}
+{"engineOnly":290833,"sceneOnly":500617,"minGridMaterial":627677,"minStandardMaterial":752502}

File diff suppressed because it is too large
+ 25357 - 22263
dist/preview release/viewer/babylon.module.d.ts


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


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


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

@@ -5,9 +5,19 @@
 ## Optimizations
 
 ## Updates
+- Support Vive Focus 3Dof controller ([TrevorDev](https://github.com/TrevorDev))
+
+### Inspector
+- Added support for `ShadowGenerator` ([Deltakosh](https://github.com/deltakosh/))
+
+### Tools
+- Added `Color3.toHSV()`, `Color3.toHSVToRef()` and `Color3.HSVtoRGBToRef()` ([Deltakosh](https://github.com/deltakosh/))
 
 ### Meshes
-- Added new CreateTiledPlane and CreateTiledBox ([JohnK](https://github.com/BabylonJSGuide/)
+- Added new CreateTiledPlane and CreateTiledBox ([JohnK](https://github.com/BabylonJSGuide/))
+
+### Tools
+- Added `ShadowGenerator.onAfterShadowMapRenderObservable` and `ShadowGenerator.onAfterShadowMapMeshRenderObservable` ([Deltakosh](https://github.com/deltakosh/))
 
 ## Bug fixes
 

+ 1 - 1
gui/src/2D/advancedDynamicTexture.ts

@@ -515,7 +515,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
                     });
                     continue;
                 }
-                var position = mesh.getBoundingInfo ? mesh.getBoundingInfo().boundingSphere.center : mesh.getAbsolutePosition();
+                var position = mesh.getBoundingInfo ? mesh.getBoundingInfo().boundingSphere.center : (Vector3.ZeroReadOnly as Vector3);
                 var projectedPosition = Vector3.Project(position, mesh.getWorldMatrix(), scene.getTransformMatrix(), globalViewport);
                 if (projectedPosition.z < 0 || projectedPosition.z > 1) {
                     control.notRenderable = true;

+ 3 - 71
gui/src/2D/controls/colorpicker.ts

@@ -48,7 +48,7 @@ export class ColorPicker extends Control {
 
         this._value.copyFrom(value);
 
-        this._RGBtoHSV(this._value, this._tmpColor);
+        this._value.toHSVToRef(this._tmpColor);
 
         this._h = this._tmpColor.r;
         this._s = Math.max(this._tmpColor.g, 0.00001);
@@ -222,7 +222,7 @@ export class ColorPicker extends Control {
                 var dist = Math.sqrt(distSq);
                 var ang = Math.atan2(y, x);
 
-                this._HSVtoRGB(ang * 180 / Math.PI + 180, dist / radius, 1, color);
+                Color3.HSVtoRGBToRef(ang * 180 / Math.PI + 180, dist / radius, 1, color);
 
                 var index = ((x + radius) + ((y + radius) * 2 * radius)) * 4;
 
@@ -264,74 +264,6 @@ export class ColorPicker extends Control {
         return canvas;
     }
 
-    private _RGBtoHSV(color: Color3, result: Color3) {
-        var r = color.r;
-        var g = color.g;
-        var b = color.b;
-
-        var max = Math.max(r, g, b);
-        var min = Math.min(r, g, b);
-        var h = 0;
-        var s = 0;
-        var v = max;
-
-        var dm = max - min;
-
-        if (max !== 0) {
-            s = dm / max;
-        }
-
-        if (max != min) {
-            if (max == r) {
-                h = (g - b) / dm;
-                if (g < b) {
-                    h += 6;
-                }
-            } else if (max == g) {
-                h = (b - r) / dm + 2;
-            } else if (max == b) {
-                h = (r - g) / dm + 4;
-            }
-            h *= 60;
-        }
-
-        result.r = h;
-        result.g = s;
-        result.b = v;
-    }
-
-    private _HSVtoRGB(hue: number, saturation: number, value: number, result: Color3) {
-        var chroma = value * saturation;
-        var h = hue / 60;
-        var x = chroma * (1 - Math.abs((h % 2) - 1));
-        var r = 0;
-        var g = 0;
-        var b = 0;
-
-        if (h >= 0 && h <= 1) {
-            r = chroma;
-            g = x;
-        } else if (h >= 1 && h <= 2) {
-            r = x;
-            g = chroma;
-        } else if (h >= 2 && h <= 3) {
-            g = chroma;
-            b = x;
-        } else if (h >= 3 && h <= 4) {
-            g = x;
-            b = chroma;
-        } else if (h >= 4 && h <= 5) {
-            r = x;
-            b = chroma;
-        } else if (h >= 5 && h <= 6) {
-            r = chroma;
-            b = x;
-        }
-
-        var m = value - chroma;
-        result.set((r + m), (g + m), (b + m));
-    }
-
     /** @hidden */
     public _draw(context: CanvasRenderingContext2D): void {
         context.save();
@@ -406,7 +338,7 @@ export class ColorPicker extends Control {
             this._v = Math.max(this._v, ColorPicker._Epsilon);
         }
 
-        this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
+        Color3.HSVtoRGBToRef(this._h, this._s, this._v, this._tmpColor);
 
         this.value = this._tmpColor;
     }

+ 99 - 5
inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonShadowLightPropertyGridComponent.tsx

@@ -7,6 +7,10 @@ import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { LockObject } from "../lockObject";
 import { GlobalState } from '../../../../globalState';
+import { OptionsLineComponent } from '../../../lines/optionsLineComponent';
+import { ShadowGenerator } from 'babylonjs/Lights/Shadows/shadowGenerator';
+import { SliderLineComponent } from '../../../lines/sliderLineComponent';
+import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
 
 interface ICommonShadowLightPropertyGridComponentProps {
     globalState: GlobalState,
@@ -20,15 +24,105 @@ export class CommonShadowLightPropertyGridComponent extends React.Component<ICom
         super(props);
     }
 
+    createShadowGenerator() {
+        const light = this.props.light;
+        const scene = light.getScene();
+        let generator = new ShadowGenerator(512, light);
+
+        scene.meshes.forEach(m => {
+            generator.addShadowCaster(m);
+            m.receiveShadows = true;
+        });
+
+        this.forceUpdate();
+    }
+
     render() {
         const light = this.props.light;
+        const generator = light.getShadowGenerator() as ShadowGenerator || null;
+
+        var blurModeOptions = [
+            { label: "None", value: ShadowGenerator.FILTER_NONE },
+            { label: "PCF", value: ShadowGenerator.FILTER_PCF },
+            { label: "PCSS", value: ShadowGenerator.FILTER_PCSS },
+            { label: "Poisson", value: ShadowGenerator.FILTER_POISSONSAMPLING },
+            { label: "Exponential", value: ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP },
+            { label: "Blurred exponential", value: ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP },
+            { label: "Close exponential", value: ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP },
+            { label: "Blurred close exponential", value: ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP },
+        ];
+
+        var filteringQualityOptions = [
+            { label: "Low", value: ShadowGenerator.QUALITY_LOW },
+            { label: "Medium", value: ShadowGenerator.QUALITY_MEDIUM },
+            { label: "High", value: ShadowGenerator.QUALITY_HIGH }
+        ];
+
+        let filter = generator ? generator.filter : 0;
 
         return (
-            <LineContainerComponent globalState={this.props.globalState} title="SHADOWS">
-                <CheckBoxLineComponent label="Shadows enabled" target={light} propertyName="shadowEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <FloatLineComponent lockObject={this.props.lockObject} label="Shadows near plane" target={light} propertyName="shadowMinZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <FloatLineComponent lockObject={this.props.lockObject} label="Shadows far plane" target={light} propertyName="shadowMaxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-            </LineContainerComponent>
+            <div>
+                <LineContainerComponent globalState={this.props.globalState} title="SHADOWS">
+                    <CheckBoxLineComponent label="Shadows enabled" target={light} propertyName="shadowEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Shadows near plane" target={light} propertyName="shadowMinZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Shadows far plane" target={light} propertyName="shadowMaxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                {
+                    generator == null &&
+                    <LineContainerComponent globalState={this.props.globalState} title="SHADOW GENERATOR">
+                        <ButtonLineComponent label="Create generator" onClick={() => this.createShadowGenerator()} />
+                    </LineContainerComponent>
+                }
+                {
+                    generator !== null &&
+                    <LineContainerComponent globalState={this.props.globalState} title="SHADOW GENERATOR">
+                        <FloatLineComponent lockObject={this.props.lockObject} label="Bias" target={generator} propertyName="bias" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <FloatLineComponent lockObject={this.props.lockObject} label="Normal bias" target={generator} propertyName="normalBias" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <SliderLineComponent label="Darkness" target={generator} minimum={0} maximum={1} step={0.01} propertyName="darkness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <CheckBoxLineComponent label="Allow transparent shadows" target={generator} propertyName="transparencyShadow" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <OptionsLineComponent label="Filter" options={blurModeOptions}
+                            onSelect={() => {
+                                this.forceUpdate();
+                            }}
+                            target={generator} propertyName="filter" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        {
+                            (filter === ShadowGenerator.FILTER_PCF || filter === ShadowGenerator.FILTER_PCSS) &&
+                            <OptionsLineComponent label="Filtering quality" options={filteringQualityOptions}
+                                onSelect={() => {
+                                    this.forceUpdate();
+                                }}
+                                target={generator} propertyName="filteringQuality" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                        {
+                            (filter === ShadowGenerator.FILTER_PCSS) &&
+                            <SliderLineComponent label="Penumbra ratio" minimum={0} maximum={0.5} step={0.001} target={generator} propertyName="contactHardeningLightSizeUVRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                        {
+                            (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                            <CheckBoxLineComponent label="Use kernel blur" target={generator} propertyName="useKernelBlur"
+                                onValueChanged={() => this.forceUpdate()}
+                                onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                        {
+                            (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                            !generator.useKernelBlur &&
+                            <SliderLineComponent label="Blur box offset" target={generator} propertyName="blurBoxOffset" minimum={1} maximum={64} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />}
+                        {
+                            (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
+                            generator.useKernelBlur &&
+                            <SliderLineComponent label="Blur kernel" target={generator} propertyName="blurKernel" minimum={1} maximum={64} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                        {
+                            (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) &&
+                            <FloatLineComponent lockObject={this.props.lockObject} label="Depth scale" target={generator} propertyName="depthScale" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                        {
+                            (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) &&
+                            <SliderLineComponent label="Blur scale" target={generator} propertyName="blurScale" minimum={1} maximum={4} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        }
+                    </LineContainerComponent>
+                }
+            </div>
         );
     }
 }

+ 16 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx

@@ -104,6 +104,18 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
             { label: "Spherical", value: Texture.SPHERICAL_MODE },
         ];
 
+        let extension = "";
+        let url = (texture as Texture).url;
+
+        if (url) {
+            for (var index = url.length - 1; index >= 0; index--) {
+                if (url[index] === ".") {
+                    break;
+                }
+                extension = url[index] + extension;
+            }
+        }
+
         return (
             <div className="pane">
                 <LineContainerComponent globalState={this.props.globalState} title="PREVIEW">
@@ -115,6 +127,10 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
                 <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                     <TextLineComponent label="Width" value={texture.getSize().width.toString()} />
                     <TextLineComponent label="Height" value={texture.getSize().height.toString()} />
+                    {
+                        extension &&
+                        <TextLineComponent label="File format" value={extension} />
+                    }
                     <TextLineComponent label="Unique ID" value={texture.uniqueId.toString()} />
                     <TextLineComponent label="Class" value={texture.getClassName()} />
                     <TextLineComponent label="Has alpha" value={texture.hasAlpha ? "Yes" : "No"} />

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

@@ -105,6 +105,7 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         var normalLines = LinesBuilder.CreateLineSystem("normalLines", { lines: lines }, scene);
         normalLines.color = color;
         normalLines.parent = mesh;
+        normalLines.reservedDataStore = { hidden: true };
 
         if (!mesh.reservedDataStore) {
             mesh.reservedDataStore = {};

+ 13 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent.tsx

@@ -23,6 +23,7 @@ import { SliderLineComponent } from "../../lines/sliderLineComponent";
 import { OptionsLineComponent } from "../../lines/optionsLineComponent";
 import { LockObject } from "./lockObject";
 import { GlobalState } from '../../../globalState';
+import { ButtonLineComponent } from '../../lines/buttonLineComponent';
 
 interface IScenePropertyGridComponentProps {
     globalState: GlobalState;
@@ -103,6 +104,15 @@ export class ScenePropertyGridComponent extends React.Component<IScenePropertyGr
         physicsEngine.setTimeStep(newValue);
     }
 
+    normalizeScene() {
+        const scene = this.props.scene;
+
+        scene.meshes.forEach((mesh) => {
+            mesh.normalizeToUnitCube(true);
+            mesh.computeWorldMatrix(true);
+        });
+    }
+
     render() {
         const scene = this.props.scene;
 
@@ -171,6 +181,9 @@ export class ScenePropertyGridComponent extends React.Component<IScenePropertyGr
                 <LineContainerComponent globalState={this.props.globalState} title="COLLISIONS" closed={true}>
                     <Vector3LineComponent label="Gravity" target={scene} propertyName="gravity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="SHADOWS" closed={true}>
+                    <ButtonLineComponent label="Normalize scene" onClick={() => this.normalizeScene()} />
+                </LineContainerComponent>
             </div>
         );
     }

+ 1 - 1
inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx

@@ -259,7 +259,7 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
         nodeContextMenus.push({
             label: "Add new directional light",
             action: () => {
-                let newDirectionalLight = new DirectionalLight("directional light", new Vector3(1, -1, 1), scene);
+                let newDirectionalLight = new DirectionalLight("directional light", new Vector3(-1, -1, -0.5), scene);
                 this.props.globalState.onSelectionChangedObservable.notifyObservers(newDirectionalLight);
             }
         });

+ 3 - 1
sandbox/index-local.html

@@ -60,7 +60,9 @@
                 </div>
             </div>
         </div>
-        <img id="logo" src='./Assets/Logo_Fullscreen.svg' />
+        <div id="logoContainer">
+            <img id="logo" src='./Assets/Logo_Fullscreen.svg' />
+        </div>
         <div id="errorZone"></div>
     </div>
     <script>

+ 10 - 2
sandbox/index.css

@@ -142,12 +142,20 @@ a:visited {
     filter:alpha(opacity=0);
 }
 
-#logo {
+#logoContainer {
     position: absolute;
     top:0;
+    left:0;
+    width: 100%;   
+    height: calc(100% - 70px);
+    pointer-events: none;
+}
+
+#logo {
+    position: absolute;
     width: 20%;
     height: 20%;
-    top: 30%;
+    top: 40%;
     left: 40%;
     pointer-events: none;
 }

+ 3 - 1
sandbox/index.html

@@ -73,7 +73,9 @@
                 </div>
             </div>
         </div>
-        <img id="logo" src='./Assets/Logo_Fullscreen.svg' />
+        <div id="logoContainer">
+            <img id="logo" src='./Assets/Logo_Fullscreen.svg' />
+        </div>
         <div id="errorZone"></div>
     </div>
     <script src="environment.js"></script>

+ 12 - 4
src/Actions/action.ts

@@ -43,10 +43,10 @@ export interface IAction {
      */
     serialize(parent: any): any;
 
-     /**
-     * Internal only
-     * @hidden
-     */
+    /**
+    * Internal only
+    * @hidden
+    */
     _prepare(): void;
 
     /**
@@ -54,6 +54,14 @@ export interface IAction {
      * @hidden
      */
     _actionManager: AbstractActionManager;
+
+    /**
+     * Adds action to chain of actions, may be a DoNothingAction
+     * @param action defines the next action to execute
+     * @returns The action passed in
+     * @see https://www.babylonjs-playground.com/#1T30HR#0
+     */
+    then(action: IAction): IAction;
 }
 
 /**

+ 5 - 1
src/Animations/animatable.ts

@@ -579,7 +579,11 @@ Scene.prototype._animate = function(): void {
     this._animationTimeLast = now;
 
     for (let index = 0; index < animatables.length; index++) {
-        animatables[index]._animate(animationTime);
+        let animatable = animatables[index];
+
+        if (!animatable._animate(animationTime) && animatable.disposeOnEnd) {
+            index--; // Array was updated
+        }
     }
 
     // Late animation bindings

+ 22 - 19
src/Behaviors/Meshes/pointerDragBehavior.ts

@@ -16,7 +16,10 @@ import "../../Meshes/Builders/planeBuilder";
  */
 export class PointerDragBehavior implements Behavior<AbstractMesh> {
     private static _AnyMouseID = -2;
-    private _attachedNode: AbstractMesh;
+    /**
+     * Abstract mesh the behavior is set on
+     */
+    public attachedNode: AbstractMesh;
     private _dragPlane: Mesh;
     private _scene: Scene;
     private _pointerObserver: Nullable<Observer<PointerInfo>>;
@@ -137,7 +140,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
      */
     public attach(ownerNode: AbstractMesh): void {
         this._scene = ownerNode.getScene();
-        this._attachedNode = ownerNode;
+        this.attachedNode = ownerNode;
 
         // Initialize drag plane to not interfere with existing scene
         if (!PointerDragBehavior._planeScene) {
@@ -158,7 +161,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
         this.lastDragPosition = new Vector3(0, 0, 0);
 
         var pickPredicate = (m: AbstractMesh) => {
-            return this._attachedNode == m || m.isDescendantOf(this._attachedNode);
+            return this.attachedNode == m || m.isDescendantOf(this.attachedNode);
         };
 
         this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo, eventState) => {
@@ -204,15 +207,15 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
 
         this._beforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {
             if (this._moving && this.moveAttached) {
-                PivotTools._RemoveAndStorePivotPoint(this._attachedNode);
+                PivotTools._RemoveAndStorePivotPoint(this.attachedNode);
                 // Slowly move mesh to avoid jitter
-                this._targetPosition.subtractToRef((this._attachedNode).absolutePosition, this._tmpVector);
+                this._targetPosition.subtractToRef((this.attachedNode).absolutePosition, this._tmpVector);
                 this._tmpVector.scaleInPlace(this.dragDeltaRatio);
-                (this._attachedNode).getAbsolutePosition().addToRef(this._tmpVector, this._tmpVector);
+                (this.attachedNode).getAbsolutePosition().addToRef(this._tmpVector, this._tmpVector);
                 if (this.validateDrag(this._tmpVector)) {
-                    (this._attachedNode).setAbsolutePosition(this._tmpVector);
+                    (this.attachedNode).setAbsolutePosition(this._tmpVector);
                 }
-                PivotTools._RestorePivotPoint(this._attachedNode);
+                PivotTools._RestorePivotPoint(this.attachedNode);
             }
         });
     }
@@ -255,18 +258,18 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
     }
 
     private _startDrag(pointerId: number, fromRay?: Ray, startPickedPoint?: Vector3) {
-        if (!this._scene.activeCamera || this.dragging || !this._attachedNode) {
+        if (!this._scene.activeCamera || this.dragging || !this.attachedNode) {
             return;
         }
 
-        PivotTools._RemoveAndStorePivotPoint(this._attachedNode);
+        PivotTools._RemoveAndStorePivotPoint(this.attachedNode);
         // Create start ray from the camera to the object
         if (fromRay) {
             this._startDragRay.direction.copyFrom(fromRay.direction);
             this._startDragRay.origin.copyFrom(fromRay.origin);
         } else {
             this._startDragRay.origin.copyFrom(this._scene.activeCamera.position);
-            this._attachedNode.getWorldMatrix().getTranslationToRef(this._tmpVector);
+            this.attachedNode.getWorldMatrix().getTranslationToRef(this._tmpVector);
             this._tmpVector.subtractToRef(this._scene.activeCamera.position, this._startDragRay.direction);
         }
 
@@ -278,7 +281,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
             this.currentDraggingPointerID = pointerId;
             this.lastDragPosition.copyFrom(pickedPoint);
             this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint, pointerId: this.currentDraggingPointerID });
-            this._targetPosition.copyFrom((this._attachedNode).absolutePosition);
+            this._targetPosition.copyFrom((this.attachedNode).absolutePosition);
 
             // Detatch camera controls
             if (this.detachCameraControls && this._scene.activeCamera && !this._scene.activeCamera.leftCamera) {
@@ -290,7 +293,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
                 }
             }
         }
-        PivotTools._RestorePivotPoint(this._attachedNode);
+        PivotTools._RestorePivotPoint(this.attachedNode);
     }
 
     private _dragDelta = new Vector3();
@@ -307,7 +310,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
             // depending on the drag mode option drag accordingly
             if (this._options.dragAxis) {
                 // Convert local drag axis to world
-                Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
+                Vector3.TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
 
                 // Project delta drag from the drag plane onto the drag axis
                 pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
@@ -340,7 +343,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
             if (this._useAlternatePickedPointAboveMaxDragAngle) {
                 // Invert ray direction along the towards object axis
                 this._tmpVector.copyFrom(ray.direction);
-                (this._attachedNode).absolutePosition.subtractToRef(ray.origin, this._alternatePickedPoint);
+                (this.attachedNode).absolutePosition.subtractToRef(ray.origin, this._alternatePickedPoint);
                 this._alternatePickedPoint.normalize();
                 this._alternatePickedPoint.scaleInPlace(this._useAlternatePickedPointAboveMaxDragAngleDragSpeed * Vector3.Dot(this._alternatePickedPoint, this._tmpVector));
                 this._tmpVector.addInPlace(this._alternatePickedPoint);
@@ -349,7 +352,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
                 var dot = Vector3.Dot(this._dragPlane.forward, this._tmpVector);
                 this._dragPlane.forward.scaleToRef(-dot, this._alternatePickedPoint);
                 this._alternatePickedPoint.addInPlace(this._tmpVector);
-                this._alternatePickedPoint.addInPlace((this._attachedNode).absolutePosition);
+                this._alternatePickedPoint.addInPlace((this.attachedNode).absolutePosition);
                 return this._alternatePickedPoint;
             } else {
                 return null;
@@ -376,7 +379,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
     private _updateDragPlanePosition(ray: Ray, dragPlanePosition: Vector3) {
         this._pointA.copyFrom(dragPlanePosition);
         if (this._options.dragAxis) {
-            this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
+            this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
 
             // Calculate plane normal in direction of camera but perpendicular to drag axis
             this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
@@ -394,7 +397,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
             this._pointA.addToRef(this._lookAt, this._lookAt);
             this._dragPlane.lookAt(this._lookAt);
         } else if (this._options.dragPlaneNormal) {
-            this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
+            this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
             this._dragPlane.position.copyFrom(this._pointA);
             this._pointA.addToRef(this._localAxis, this._lookAt);
             this._dragPlane.lookAt(this._lookAt);
@@ -403,7 +406,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
             this._dragPlane.lookAt(ray.origin);
         }
         // Update the position of the drag plane so it doesn't get out of sync with the node (eg. when moving back and forth quickly)
-        this._dragPlane.position.copyFrom(this._attachedNode.absolutePosition);
+        this._dragPlane.position.copyFrom(this.attachedNode.absolutePosition);
 
         this._dragPlane.computeWorldMatrix(true);
     }

+ 2 - 1
src/Gamepads/Controllers/gearVRController.ts

@@ -86,7 +86,8 @@ export class GearVRController extends WebVRController {
 PoseEnabledControllerHelper._ControllerFactories.push({
     canCreate: (gamepadInfo) => {
         return gamepadInfo.id.indexOf(GearVRController.GAMEPAD_ID_PREFIX) === 0 ||
-            gamepadInfo.id.indexOf('Oculus Go') !== -1;
+            gamepadInfo.id.indexOf('Oculus Go') !== -1 ||
+            gamepadInfo.id.indexOf('Vive Focus') !== -1;
     },
     create: (gamepadInfo) => {
         return new GearVRController(gamepadInfo);

+ 3 - 2
src/Gamepads/gamepadManager.ts

@@ -167,12 +167,13 @@ export class GamepadManager {
         }
 
         var newGamepad;
+        var dualShock: boolean = ((<string>gamepad.id).search("054c") !== -1);
         var xboxOne: boolean = ((<string>gamepad.id).search("Xbox One") !== -1);
         if (xboxOne || (<string>gamepad.id).search("Xbox 360") !== -1 || (<string>gamepad.id).search("xinput") !== -1) {
             newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad, xboxOne);
         }
-        // if pose is supported, use the (WebVR) pose enabled controller
-        else if (gamepad.pose) {
+        // if pose is supported, use the (WebVR) pose enabled controller, ignore DualShock (ps4) as they have a pose but should not be used for webVR
+        else if (gamepad.pose && !dualShock) {
             newGamepad = PoseEnabledControllerHelper.InitiateController(gamepad);
         }
         else {

+ 57 - 0
src/Lights/Shadows/shadowGenerator.ts

@@ -222,11 +222,22 @@ export class ShadowGenerator implements IShadowGenerator {
     public onBeforeShadowMapRenderObservable = new Observable<Effect>();
 
     /**
+     * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
+     */
+    public onAfterShadowMapRenderObservable = new Observable<Effect>();
+
+    /**
      * Observable triggered before a mesh is rendered in the shadow map.
      * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
      */
     public onBeforeShadowMapRenderMeshObservable = new Observable<Mesh>();
 
+    /**
+     * Observable triggered after a mesh is rendered in the shadow map.
+     * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
+     */
+    public onAfterShadowMapRenderMeshObservable = new Observable<Mesh>();
+
     private _bias = 0.00005;
     /**
      * Gets the bias: offset applied on the depth preventing acnea (in light direction).
@@ -516,7 +527,15 @@ export class ShadowGenerator implements IShadowGenerator {
      * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
      */
     public set filteringQuality(filteringQuality: number) {
+        if (this._filteringQuality === filteringQuality) {
+            return;
+        }
+
         this._filteringQuality = filteringQuality;
+
+        this._disposeBlurPostProcesses();
+        this._applyFilterValues();
+        this._light._markMeshesAsLightDirty();
     }
 
     /**
@@ -562,6 +581,16 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     private _darkness = 0;
+
+    /** Gets or sets the actual darkness of a shadow */
+    public get darkness() {
+        return this._darkness;
+    }
+
+    public set darkness(value: number) {
+        this.setDarkness(value);
+    }
+
     /**
      * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
      * 0 means strongest and 1 would means no shadow.
@@ -589,6 +618,16 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     private _transparencyShadow = false;
+
+    /** Gets or sets the ability to have transparent shadow  */
+    public get transparencyShadow() {
+        return this._transparencyShadow;
+    }
+
+    public set transparencyShadow(value: boolean) {
+        this.setTransparencyShadow(value);
+    }
+
     /**
      * Sets the ability to have transparent shadow (boolean).
      * @param transparent True if transparent else False
@@ -621,6 +660,14 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     /**
+     * Gets the class name of that object
+     * @returns "ShadowGenerator"
+     */
+    public getClassName(): string {
+        return "ShadowGenerator";
+    }
+
+    /**
      * Helper function to add a mesh and its descendants to the list of shadow casters.
      * @param mesh Mesh to add
      * @param includeDescendants boolean indicating if the descendants should be added. Default to true
@@ -985,6 +1032,11 @@ export class ShadowGenerator implements IShadowGenerator {
             if (this.forceBackFacesOnly) {
                 engine.setState(true, 0, false, false);
             }
+
+            // Observables
+            this.onAfterShadowMapRenderObservable.notifyObservers(this._effect);
+            this.onAfterShadowMapRenderMeshObservable.notifyObservers(mesh);
+
         } else {
             // Need to reset refresh rate of the shadowMap
             if (this._shadowMap) {
@@ -1464,6 +1516,11 @@ export class ShadowGenerator implements IShadowGenerator {
             this._light._shadowGenerator = null;
             this._light._markMeshesAsLightDirty();
         }
+
+        this.onBeforeShadowMapRenderMeshObservable.clear();
+        this.onBeforeShadowMapRenderObservable.clear();
+        this.onAfterShadowMapRenderMeshObservable.clear();
+        this.onAfterShadowMapRenderObservable.clear();
     }
 
     /**

+ 4 - 6
src/Loading/loadingScreen.ts

@@ -110,12 +110,10 @@ export class DefaultLoadingScreen implements ILoadingScreen {
         }
 
         imgBack.style.position = "absolute";
-        imgBack.style.left = "50%";
-        imgBack.style.top = "50%";
-        imgBack.style.width = "10vw";
-        imgBack.style.height = "10vw";
-        imgBack.style.marginLeft = "-5vw";
-        imgBack.style.marginTop = "-5vw";
+        imgBack.style.left = "40%";
+        imgBack.style.top = "40%";
+        imgBack.style.width = "20%";
+        imgBack.style.height = "20%";
 
         // Loading spinner
         var imgSpinner = new Image();

+ 1 - 1
src/Materials/PBR/pbrBaseMaterial.ts

@@ -250,7 +250,7 @@ export class PBRMaterialDefines extends MaterialDefines
  *
  * This offers the main features of a standard PBR material.
  * For more information, please refer to the documentation :
- * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+ * https://doc.babylonjs.com/how_to/physically_based_rendering
  */
 export abstract class PBRBaseMaterial extends PushMaterial {
     /**

+ 1 - 1
src/Materials/PBR/pbrMaterial.ts

@@ -16,7 +16,7 @@ import { _TypeStore } from '../../Misc/typeStore';
  *
  * This offers the main features of a standard PBR material.
  * For more information, please refer to the documentation :
- * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
+ * https://doc.babylonjs.com/how_to/physically_based_rendering
  */
 export class PBRMaterial extends PBRBaseMaterial {
     /**

+ 0 - 2
src/Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts

@@ -3,7 +3,6 @@ import { Scene } from "../../../scene";
 import { SceneComponentConstants, ISceneComponent } from "../../../sceneComponent";
 import { _TimeToken } from "../../../Instrumentation/timeToken";
 import { _DepthCullingState, _StencilState, _AlphaState } from "../../../States/index";
-import { Layer } from "../../../Layers/layer";
 
 import { ProceduralTexture } from "./proceduralTexture";
 
@@ -38,7 +37,6 @@ export class ProceduralTextureSceneComponent implements ISceneComponent {
     constructor(scene: Scene) {
         this.scene = scene;
         this.scene.proceduralTextures = new Array<ProceduralTexture>();
-        scene.layers = new Array<Layer>();
     }
 
     /**

+ 99 - 0
src/Maths/math.ts

@@ -316,6 +316,58 @@ export class Color3 {
     }
 
     /**
+     * Converts current color in rgb space to HSV values
+     * @returns a new color3 representing the HSV values
+     */
+    public toHSV(): Color3 {
+        let result = new Color3();
+
+        this.toHSVToRef(result);
+
+        return result;
+    }
+
+    /**
+     * Converts current color in rgb space to HSV values
+     * @param result defines the Color3 where to store the HSV values
+     */
+    public toHSVToRef(result: Color3) {
+        var r = this.r;
+        var g = this.g;
+        var b = this.b;
+
+        var max = Math.max(r, g, b);
+        var min = Math.min(r, g, b);
+        var h = 0;
+        var s = 0;
+        var v = max;
+
+        var dm = max - min;
+
+        if (max !== 0) {
+            s = dm / max;
+        }
+
+        if (max != min) {
+            if (max == r) {
+                h = (g - b) / dm;
+                if (g < b) {
+                    h += 6;
+                }
+            } else if (max == g) {
+                h = (b - r) / dm + 2;
+            } else if (max == b) {
+                h = (r - g) / dm + 4;
+            }
+            h *= 60;
+        }
+
+        result.r = h;
+        result.g = s;
+        result.b = v;
+    }
+
+    /**
      * Converts the Color3 values to linear space and stores the result in "convertedColor"
      * @param convertedColor defines the Color3 object where to store the linear space version
      * @returns the unmodified Color3
@@ -354,6 +406,45 @@ export class Color3 {
     private static _BlackReadOnly = Color3.Black() as DeepImmutable<Color3>;
 
     /**
+     * Convert Hue, saturation and value to a Color3 (RGB)
+     * @param hue defines the hue
+     * @param saturation defines the saturation
+     * @param value defines the value
+     * @param result defines the Color3 where to store the RGB values
+     */
+    public static HSVtoRGBToRef(hue: number, saturation: number, value: number, result: Color3) {
+        var chroma = value * saturation;
+        var h = hue / 60;
+        var x = chroma * (1 - Math.abs((h % 2) - 1));
+        var r = 0;
+        var g = 0;
+        var b = 0;
+
+        if (h >= 0 && h <= 1) {
+            r = chroma;
+            g = x;
+        } else if (h >= 1 && h <= 2) {
+            r = x;
+            g = chroma;
+        } else if (h >= 2 && h <= 3) {
+            g = chroma;
+            b = x;
+        } else if (h >= 3 && h <= 4) {
+            g = x;
+            b = chroma;
+        } else if (h >= 4 && h <= 5) {
+            r = x;
+            b = chroma;
+        } else if (h >= 5 && h <= 6) {
+            r = chroma;
+            b = x;
+        }
+
+        var m = value - chroma;
+        result.set((r + m), (g + m), (b + m));
+    }
+
+    /**
      * Creates a new Color3 from the string containing valid hexadecimal values
      * @param hex defines a string containing valid hexadecimal values
      * @returns a new Color3 object
@@ -1554,6 +1645,7 @@ export class Vector2 {
  */
 export class Vector3 {
     private static _UpReadOnly = Vector3.Up() as DeepImmutable<Vector3>;
+    private static _ZeroReadOnly = Vector3.Zero() as DeepImmutable<Vector3>;
 
     /**
      * Creates a new Vector3 object from the given x, y, z (floats) coordinates.
@@ -2273,6 +2365,13 @@ export class Vector3 {
     }
 
     /**
+     * Gets a zero Vector3 that must not be updated
+     */
+    public static get ZeroReadOnly(): DeepImmutable<Vector3> {
+        return Vector3._ZeroReadOnly;
+    }
+
+    /**
      * Returns a new Vector3 set to (0.0, -1.0, 0.0)
      * @returns a new down Vector3
      */

+ 14 - 6
src/Meshes/Builders/cylinderBuilder.ts

@@ -4,7 +4,7 @@ import { VertexData } from "../mesh.vertexData";
 import { Scene } from "../../scene";
 import { Nullable } from "../../types";
 
-VertexData.CreateCylinder = function(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
+VertexData.CreateCylinder = function(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, enclose?: boolean, cap?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
     var height: number = options.height || 2;
     var diameterTop: number = (options.diameterTop === 0) ? 0 : options.diameterTop || options.diameter || 1;
     var diameterBottom: number = (options.diameterBottom === 0) ? 0 : options.diameterBottom || options.diameter || 1;
@@ -12,6 +12,7 @@ VertexData.CreateCylinder = function(options: { height?: number, diameterTop?: n
     var subdivisions: number = options.subdivisions || 1;
     var hasRings: boolean = options.hasRings ? true : false;
     var enclose: boolean = options.enclose ? true : false;
+    var cap = options.cap || Mesh.CAP_ALL;
     var arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
     var sideOrientation: number = (options.sideOrientation === 0) ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;
     var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(3);
@@ -235,9 +236,15 @@ VertexData.CreateCylinder = function(options: { height?: number, diameterTop?: n
         }
     };
 
-    // add caps to geometry
-    createCylinderCap(false);
-    createCylinderCap(true);
+    // add caps to geometry based on cap parameter
+    if ((cap === Mesh.CAP_START)
+        || (cap === Mesh.CAP_ALL)) {
+        createCylinderCap(false);
+    }
+    if ((cap === Mesh.CAP_END)
+        || (cap === Mesh.CAP_ALL)) {
+        createCylinderCap(true);
+    }
 
     // Sides
     VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
@@ -291,6 +298,7 @@ export class CylinderBuilder {
      * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
      * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
      * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+     * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
      * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
      * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
      * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -309,7 +317,7 @@ export class CylinderBuilder {
      * @returns the cylinder mesh
      * @see https://doc.babylonjs.com/how_to/set_shapes#cylinder-or-cone
      */
-    public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
+    public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, cap?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
         var cylinder = new Mesh(name, scene);
 
         options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);
@@ -321,4 +329,4 @@ export class CylinderBuilder {
 
         return cylinder;
     }
-}
+}

+ 10 - 5
src/Meshes/linesMesh.ts

@@ -1,6 +1,6 @@
 import { Nullable } from "../types";
 import { Scene } from "../scene";
-import { Color3 } from "../Maths/math";
+import { Color3, Color4 } from "../Maths/math";
 import { Node } from "../node";
 import { VertexBuffer } from "../Meshes/buffer";
 import { SubMesh } from "../Meshes/subMesh";
@@ -9,10 +9,10 @@ import { InstancedMesh } from "../Meshes/instancedMesh";
 import { Effect } from "../Materials/effect";
 import { Material } from "../Materials/material";
 import { ShaderMaterial } from "../Materials/shaderMaterial";
+import { MaterialHelper } from '../Materials/materialHelper';
 
 import "../Shaders/color.fragment";
 import "../Shaders/color.vertex";
-import { MaterialHelper } from '../Materials/materialHelper';
 
 /**
  * Line mesh
@@ -37,6 +37,8 @@ export class LinesMesh extends Mesh {
 
     private _colorShader: ShaderMaterial;
 
+    private color4 : Color4;
+
     /**
      * Creates a new LinesMesh
      * @param name defines the name
@@ -58,11 +60,11 @@ export class LinesMesh extends Mesh {
         /**
          * If vertex color should be applied to the mesh
          */
-        public useVertexColor?: boolean,
+        public readonly useVertexColor?: boolean,
         /**
          * If vertex alpha should be applied to the mesh
          */
-        public useVertexAlpha?: boolean
+        public readonly useVertexAlpha?: boolean
     ) {
         super(name, scene, parent, source, doNotCloneChildren);
 
@@ -89,6 +91,7 @@ export class LinesMesh extends Mesh {
 
         if (!useVertexColor) {
             options.uniforms.push("color");
+            this.color4 = new Color4();
         }
         else {
             options.defines.push("#define VERTEXCOLOR");
@@ -177,7 +180,9 @@ export class LinesMesh extends Mesh {
 
         // Color
         if (!this.useVertexColor) {
-            this._colorShader.setColor4("color", this.color.toColor4(this.alpha));
+            const { r, g, b } = this.color;
+            this.color4.set(r, g, b, this.alpha);
+            this._colorShader.setColor4("color", this.color4);
         }
 
         // Clip planes

+ 7 - 3
src/Meshes/mesh.ts

@@ -737,6 +737,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
      * Returns the mesh VertexBuffer object from the requested `kind`
      * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
      * - VertexBuffer.PositionKind
+     * - VertexBuffer.NormalKind
      * - VertexBuffer.UVKind
      * - VertexBuffer.UV2Kind
      * - VertexBuffer.UV3Kind
@@ -761,6 +762,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
      * Tests if a specific vertex buffer is associated with this mesh
      * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
      * - VertexBuffer.PositionKind
+     * - VertexBuffer.NormalKind
      * - VertexBuffer.UVKind
      * - VertexBuffer.UV2Kind
      * - VertexBuffer.UV3Kind
@@ -815,6 +817,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
      * Returns a string which contains the list of existing `kinds` of Vertex Data associated with this mesh.
      * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
      * - VertexBuffer.PositionKind
+     * - VertexBuffer.NormalKind
      * - VertexBuffer.UVKind
      * - VertexBuffer.UV2Kind
      * - VertexBuffer.UV3Kind
@@ -1544,8 +1547,6 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
     /** @hidden */
     public _freeze() {
-        this._instanceDataStorage.isFrozen = true;
-
         if (!this.subMeshes) {
             return;
         }
@@ -1554,6 +1555,9 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         for (var index = 0; index < this.subMeshes.length; index++) {
             this._getInstancesRenderList(index);
         }
+
+        this._effectiveMaterial = null;
+        this._instanceDataStorage.isFrozen = true;
     }
 
     /** @hidden */
@@ -2583,7 +2587,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             }
 
             vertex_data.indices = indices;
-            vertex_data.applyToMesh(this);
+            vertex_data.applyToMesh(this, this.isVertexBufferUpdatable(VertexBuffer.PositionKind));
         }
     }
 

+ 2 - 1
src/Meshes/meshBuilder.ts

@@ -157,6 +157,7 @@ export class MeshBuilder {
      * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
      * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
      * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
+     * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
      * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
      * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
      * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
@@ -175,7 +176,7 @@ export class MeshBuilder {
      * @returns the cylinder mesh
      * @see https://doc.babylonjs.com/how_to/set_shapes#cylinder-or-cone
      */
-    public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Nullable<Scene> = null): Mesh {
+    public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, cap?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Nullable<Scene> = null): Mesh {
         return CylinderBuilder.CreateCylinder(name, options, scene);
     }
 

+ 7 - 0
src/Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts

@@ -148,6 +148,13 @@ export class CubeMapToSphericalPolynomialTools {
                         b = Math.pow(Scalar.Clamp(b), ToLinearSpace);
                     }
 
+                    // Prevent to explode in case of really high dynamic ranges.
+                    // sh 3 would not be enough to accurately represent it.
+                    const max = 4096;
+                    r = Scalar.Clamp(r, 0, max);
+                    g = Scalar.Clamp(g, 0, max);
+                    b = Scalar.Clamp(b, 0, max);
+
                     var color = new Color3(r, g, b);
 
                     sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);

+ 4 - 3
src/Rendering/renderingGroup.ts

@@ -1,7 +1,7 @@
 import { SmartArray } from "../Misc/smartArray";
 import { SubMesh } from "../Meshes/subMesh";
 import { AbstractMesh } from "../Meshes/abstractMesh";
-import { Nullable } from "../types";
+import { Nullable, DeepImmutable } from "../types";
 import { Vector3 } from "../Maths/math";
 import { IParticleSystem } from "../Particles/IParticleSystem";
 import { IEdgesRenderer } from "./edgesRenderer";
@@ -18,6 +18,7 @@ import { Camera } from "../Cameras/camera";
  * @hidden
  */
 export class RenderingGroup {
+    private static _zeroVector : DeepImmutable<Vector3> = Vector3.Zero();
     private _scene: Scene;
     private _opaqueSubMeshes = new SmartArray<SubMesh>(256);
     private _transparentSubMeshes = new SmartArray<SubMesh>(256);
@@ -202,11 +203,11 @@ export class RenderingGroup {
     private static renderSorted(subMeshes: SmartArray<SubMesh>, sortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>, camera: Nullable<Camera>, transparent: boolean): void {
         let subIndex = 0;
         let subMesh: SubMesh;
-        let cameraPosition = camera ? camera.globalPosition : Vector3.Zero();
+        let cameraPosition = camera ? camera.globalPosition : RenderingGroup._zeroVector;
         for (; subIndex < subMeshes.length; subIndex++) {
             subMesh = subMeshes.data[subIndex];
             subMesh._alphaIndex = subMesh.getMesh().alphaIndex;
-            subMesh._distanceToCamera = subMesh.getBoundingInfo().boundingSphere.centerWorld.subtract(cameraPosition).length();
+            subMesh._distanceToCamera = Vector3.Distance(subMesh.getBoundingInfo().boundingSphere.centerWorld, cameraPosition);
         }
 
         let sortedArray = subMeshes.data.slice(0, subMeshes.length);

+ 1 - 1
src/assetContainer.ts

@@ -251,7 +251,7 @@ export class AssetContainer extends AbstractScene {
 
         for (let key in this) {
             if (this.hasOwnProperty(key)) {
-                (<any>this)[key] = (<any>this)[key] || [];
+                (<any>this)[key] = (<any>this)[key] || (key === "environmentTexture" ? null : []);
                 this._moveAssets((<any>this.scene)[key], (<any>this)[key], (<any>keepAssets)[key]);
             }
         }