Prechádzať zdrojové kódy

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

Guide 6 rokov pred
rodič
commit
4c89052107
45 zmenil súbory, kde vykonal 3139 pridanie a 2425 odobranie
  1. 694 638
      Playground/babylon.d.txt
  2. 2 2
      Tools/DevLoader/BabylonLoader.js
  3. 567 510
      dist/preview release/babylon.d.ts
  4. 2 2
      dist/preview release/babylon.js
  5. 351 135
      dist/preview release/babylon.max.js
  6. 1 1
      dist/preview release/babylon.max.js.map
  7. 634 545
      dist/preview release/babylon.module.d.ts
  8. 135 125
      dist/preview release/gui/babylon.gui.d.ts
  9. 89 62
      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. 273 252
      dist/preview release/gui/babylon.gui.module.d.ts
  13. 47 31
      dist/preview release/viewer/babylon.viewer.js
  14. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  15. 2 1
      dist/preview release/what's new.md
  16. 3 3
      materialsLibrary/test/addfur.js
  17. 21 0
      src/Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts
  18. 22 0
      src/Cameras/Inputs/freeCameraDeviceOrientationInput.ts
  19. 22 0
      src/Cameras/Inputs/freeCameraVirtualJoystickInput.ts
  20. 4 0
      src/Cameras/RigModes/index.ts
  21. 8 0
      src/Cameras/RigModes/stereoscopicAnaglyphRigMode.ts
  22. 10 0
      src/Cameras/RigModes/stereoscopicRigMode.ts
  23. 27 0
      src/Cameras/RigModes/vrRigMode.ts
  24. 38 0
      src/Cameras/RigModes/webVRRigMode.ts
  25. 3 0
      src/Cameras/Stereoscopic/anaglyphArcRotateCamera.ts
  26. 3 0
      src/Cameras/Stereoscopic/anaglyphFreeCamera.ts
  27. 3 0
      src/Cameras/Stereoscopic/anaglyphGamepadCamera.ts
  28. 3 0
      src/Cameras/Stereoscopic/anaglyphUniversalCamera.ts
  29. 3 0
      src/Cameras/Stereoscopic/stereoscopicArcRotateCamera.ts
  30. 3 0
      src/Cameras/Stereoscopic/stereoscopicFreeCamera.ts
  31. 3 0
      src/Cameras/Stereoscopic/stereoscopicGamepadCamera.ts
  32. 3 0
      src/Cameras/Stereoscopic/stereoscopicUniversalCamera.ts
  33. 5 0
      src/Cameras/VR/vrDeviceOrientationArcRotateCamera.ts
  34. 3 0
      src/Cameras/VR/vrDeviceOrientationFreeCamera.ts
  35. 2 2
      src/Cameras/VR/vrExperienceHelper.ts
  36. 8 2
      src/Cameras/VR/webVRCamera.ts
  37. 0 10
      src/Cameras/arcRotateCameraInputsManager.ts
  38. 36 75
      src/Cameras/camera.ts
  39. 2 0
      src/Cameras/deviceOrientationCamera.ts
  40. 0 20
      src/Cameras/freeCameraInputsManager.ts
  41. 2 1
      src/Cameras/index.ts
  42. 3 0
      src/Cameras/virtualJoysticksCamera.ts
  43. 89 4
      src/Lights/Shadows/shadowGenerator.ts
  44. 8 0
      src/PostProcesses/postProcess.ts
  45. 2 1
      src/Sprites/spriteManager.ts

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 694 - 638
Playground/babylon.d.txt


+ 2 - 2
Tools/DevLoader/BabylonLoader.js

@@ -192,7 +192,7 @@ var BABYLONDEVTOOLS;
 
         Loader.prototype.loadCoreDev = function() {
             // Es6 core import
-            this.loadESMScript(babylonJSPath + "/.temp/" + localDevES6FolderName + "/core/legacy/legacy.js");
+            this.loadESMScript(babylonJSPath + "/.temp/" + localDevES6FolderName + "/core/Legacy/legacy.js");
         }
 
         Loader.prototype.loadModule = function(moduleName, module) {
@@ -260,4 +260,4 @@ var BABYLONDEVTOOLS;
     var loader = new Loader();
     BABYLONDEVTOOLS.Loader = loader;
 
-})(BABYLONDEVTOOLS || (BABYLONDEVTOOLS = {}))
+})(BABYLONDEVTOOLS || (BABYLONDEVTOOLS = {}))

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 567 - 510
dist/preview release/babylon.d.ts


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 2
dist/preview release/babylon.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 351 - 135
dist/preview release/babylon.max.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/babylon.max.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 634 - 545
dist/preview release/babylon.module.d.ts


+ 135 - 125
dist/preview release/gui/babylon.gui.d.ts

@@ -114,6 +114,118 @@ declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
     /**
+     * Class used to transport BABYLON.Vector2 information for pointer events
+     */
+    export class Vector2WithInfo extends BABYLON.Vector2 {
+        /** defines the current mouse button index */
+        buttonIndex: number;
+        /**
+         * Creates a new Vector2WithInfo
+         * @param source defines the vector2 data to transport
+         * @param buttonIndex defines the current mouse button index
+         */
+        constructor(source: BABYLON.Vector2, 
+        /** defines the current mouse button index */
+        buttonIndex?: number);
+    }
+    /** Class used to provide 2D matrix features */
+    export class Matrix2D {
+        /** Gets the internal array of 6 floats used to store matrix data */
+        m: Float32Array;
+        /**
+         * Creates a new matrix
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         */
+        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
+        /**
+         * Fills the matrix from direct values
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         * @returns the current modified matrix
+         */
+        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
+        /**
+         * Gets matrix determinant
+         * @returns the determinant
+         */
+        determinant(): number;
+        /**
+         * Inverses the matrix and stores it in a target matrix
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        invertToRef(result: Matrix2D): Matrix2D;
+        /**
+         * Multiplies the current matrix with another one
+         * @param other defines the second operand
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
+        /**
+         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+         * @param x defines the x coordinate to transform
+         * @param y defines the x coordinate to transform
+         * @param result defines the target vector2
+         * @returns the current matrix
+         */
+        transformCoordinates(x: number, y: number, result: BABYLON.Vector2): Matrix2D;
+        /**
+         * Creates an identity matrix
+         * @returns a new matrix
+         */
+        static Identity(): Matrix2D;
+        /**
+         * Creates a translation matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the translation
+         * @param y defines the y coordinate of the translation
+         * @param result defines the target matrix
+         */
+        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a scaling matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the scaling
+         * @param y defines the y coordinate of the scaling
+         * @param result defines the target matrix
+         */
+        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a rotation matrix and stores it in a target matrix
+         * @param angle defines the rotation angle
+         * @param result defines the target matrix
+         */
+        static RotationToRef(angle: number, result: Matrix2D): void;
+        private static _TempPreTranslationMatrix;
+        private static _TempPostTranslationMatrix;
+        private static _TempRotationMatrix;
+        private static _TempScalingMatrix;
+        private static _TempCompose0;
+        private static _TempCompose1;
+        private static _TempCompose2;
+        /**
+         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
+         * @param tx defines the x coordinate of the translation
+         * @param ty defines the y coordinate of the translation
+         * @param angle defines the rotation angle
+         * @param scaleX defines the x coordinate of the scaling
+         * @param scaleY defines the y coordinate of the scaling
+         * @param parentMatrix defines the parent matrix to multiply by (can be null)
+         * @param result defines the target matrix
+         */
+        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: BABYLON.Nullable<Matrix2D>, result: Matrix2D): void;
+    }
+}
+declare module BABYLON.GUI {
+    /**
      * Class used to store 2D control sizes
      */
     export class Measure {
@@ -155,6 +267,19 @@ declare module BABYLON.GUI {
          */
         copyFromFloats(left: number, top: number, width: number, height: number): void;
         /**
+         * Computes the axis aligned bounding box measure for two given measures
+         * @param a Input measure
+         * @param b Input measure
+         * @param result the resulting bounding measure
+         */
+        static CombineToRef(a: Measure, b: Measure, result: Measure): void;
+        /**
+         * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+         * @param transform the matrix to transform the measure before computing the AABB
+         * @param result the resulting AABB
+         */
+        transformToRef(transform: Matrix2D, result: Measure): void;
+        /**
          * Check equality between this measure and another one
          * @param other defines the other measures
          * @returns true if both measures are equals
@@ -357,20 +482,15 @@ declare module BABYLON.GUI {
          * Gets or sets a boolean indicating if the InvalidateRect optimization should be turned on
          */
         useInvalidateRectOptimization: boolean;
-        private _clearRectangle;
         private _invalidatedRectangle;
         /**
          * Invalidates a rectangle area on the gui texture
-         * @param clearMinX left most position of the rectangle to clear in the texture
-         * @param clearMinY top most position of the rectangle to clear in the texture
-         * @param clearMaxX right most position of the rectangle to clear in the texture
-         * @param clearMaxY bottom most position of the rectangle to clear in the texture
-         * @param minX left most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param minY top most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxX right most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxY bottom most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
+         * @param invalidMinX left most position of the rectangle to invalidate in the texture
+         * @param invalidMinY top most position of the rectangle to invalidate in the texture
+         * @param invalidMaxX right most position of the rectangle to invalidate in the texture
+         * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
          */
-        invalidateRect(clearMinX: number, clearMinY: number, clearMaxX: number, clearMaxY: number, minX: number, minY: number, maxX: number, maxY: number): void;
+        invalidateRect(invalidMinX: number, invalidMinY: number, invalidMaxX: number, invalidMaxY: number): void;
         /**
         * Marks the texture as dirty forcing a complete update
         */
@@ -477,118 +597,6 @@ declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
     /**
-     * Class used to transport BABYLON.Vector2 information for pointer events
-     */
-    export class Vector2WithInfo extends BABYLON.Vector2 {
-        /** defines the current mouse button index */
-        buttonIndex: number;
-        /**
-         * Creates a new Vector2WithInfo
-         * @param source defines the vector2 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */
-        constructor(source: BABYLON.Vector2, 
-        /** defines the current mouse button index */
-        buttonIndex?: number);
-    }
-    /** Class used to provide 2D matrix features */
-    export class Matrix2D {
-        /** Gets the internal array of 6 floats used to store matrix data */
-        m: Float32Array;
-        /**
-         * Creates a new matrix
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         */
-        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
-        /**
-         * Fills the matrix from direct values
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         * @returns the current modified matrix
-         */
-        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
-        /**
-         * Gets matrix determinant
-         * @returns the determinant
-         */
-        determinant(): number;
-        /**
-         * Inverses the matrix and stores it in a target matrix
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        invertToRef(result: Matrix2D): Matrix2D;
-        /**
-         * Multiplies the current matrix with another one
-         * @param other defines the second operand
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
-        /**
-         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
-         * @param x defines the x coordinate to transform
-         * @param y defines the x coordinate to transform
-         * @param result defines the target vector2
-         * @returns the current matrix
-         */
-        transformCoordinates(x: number, y: number, result: BABYLON.Vector2): Matrix2D;
-        /**
-         * Creates an identity matrix
-         * @returns a new matrix
-         */
-        static Identity(): Matrix2D;
-        /**
-         * Creates a translation matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the translation
-         * @param y defines the y coordinate of the translation
-         * @param result defines the target matrix
-         */
-        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a scaling matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the scaling
-         * @param y defines the y coordinate of the scaling
-         * @param result defines the target matrix
-         */
-        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a rotation matrix and stores it in a target matrix
-         * @param angle defines the rotation angle
-         * @param result defines the target matrix
-         */
-        static RotationToRef(angle: number, result: Matrix2D): void;
-        private static _TempPreTranslationMatrix;
-        private static _TempPostTranslationMatrix;
-        private static _TempRotationMatrix;
-        private static _TempScalingMatrix;
-        private static _TempCompose0;
-        private static _TempCompose1;
-        private static _TempCompose2;
-        /**
-         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
-         * @param tx defines the x coordinate of the translation
-         * @param ty defines the y coordinate of the translation
-         * @param angle defines the rotation angle
-         * @param scaleX defines the x coordinate of the scaling
-         * @param scaleY defines the y coordinate of the scaling
-         * @param parentMatrix defines the parent matrix to multiply by (can be null)
-         * @param result defines the target matrix
-         */
-        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: BABYLON.Nullable<Matrix2D>, result: Matrix2D): void;
-    }
-}
-declare module BABYLON.GUI {
-    /**
      * Root class used for all 2D controls
      * @see http://doc.babylonjs.com/how_to/gui#controls
      */
@@ -637,7 +645,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         _tempParentMeasure: Measure;
         /** @hidden */
-        _tempCurrentMeasure: Measure;
+        _prevCurrentMeasureTransformedIntoGlobalSpace: Measure;
         /** @hidden */
         protected _cachedParentMeasure: Measure;
         private _paddingLeft;
@@ -653,7 +661,8 @@ declare module BABYLON.GUI {
         private _rotation;
         private _transformCenterX;
         private _transformCenterY;
-        private _transformMatrix;
+        /** @hidden */
+        _transformMatrix: Matrix2D;
         /** @hidden */
         protected _invertTransformMatrix: Matrix2D;
         /** @hidden */
@@ -1022,7 +1031,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         _intersectsRect(rect: Measure): boolean;
         /** @hidden */
-        protected invalidateRect(left: number, top: number, right: number, bottom: number): void;
+        protected invalidateRect(): void;
         /** @hidden */
         _markAsDirty(force?: boolean): void;
         /** @hidden */
@@ -1053,6 +1062,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         protected _clipForChildren(context: CanvasRenderingContext2D): void;
         private static _ClipMeasure;
+        private _tmpMeasureA;
         private _clip;
         /** @hidden */
         _render(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): boolean;

+ 89 - 62
dist/preview release/gui/babylon.gui.js

@@ -592,7 +592,7 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
         */
         _this.premulAlpha = false;
         _this._useInvalidateRectOptimization = true;
-        _this._clearRectangle = null;
+        // Invalidated rectangle which is the combination of all invalidated controls after they have been rotated into absolute position
         _this._invalidatedRectangle = null;
         _this._clearMeasure = new _measure__WEBPACK_IMPORTED_MODULE_4__["Measure"](0, 0, 0, 0);
         /** @hidden */
@@ -885,35 +885,24 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
     });
     /**
      * Invalidates a rectangle area on the gui texture
-     * @param clearMinX left most position of the rectangle to clear in the texture
-     * @param clearMinY top most position of the rectangle to clear in the texture
-     * @param clearMaxX right most position of the rectangle to clear in the texture
-     * @param clearMaxY bottom most position of the rectangle to clear in the texture
-     * @param minX left most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param minY top most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param maxX right most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param maxY bottom most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     */
-    AdvancedDynamicTexture.prototype.invalidateRect = function (clearMinX, clearMinY, clearMaxX, clearMaxY, minX, minY, maxX, maxY) {
+     * @param invalidMinX left most position of the rectangle to invalidate in the texture
+     * @param invalidMinY top most position of the rectangle to invalidate in the texture
+     * @param invalidMaxX right most position of the rectangle to invalidate in the texture
+     * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
+     */
+    AdvancedDynamicTexture.prototype.invalidateRect = function (invalidMinX, invalidMinY, invalidMaxX, invalidMaxY) {
         if (!this._useInvalidateRectOptimization) {
             return;
         }
-        if (!this._clearRectangle || !this._invalidatedRectangle) {
-            this._clearRectangle = new _measure__WEBPACK_IMPORTED_MODULE_4__["Measure"](clearMinX, clearMinY, clearMaxX - clearMinX + 1, clearMaxY - clearMinY + 1);
-            this._invalidatedRectangle = new _measure__WEBPACK_IMPORTED_MODULE_4__["Measure"](minX, minY, maxX - minX + 1, maxY - minY + 1);
+        if (!this._invalidatedRectangle) {
+            this._invalidatedRectangle = new _measure__WEBPACK_IMPORTED_MODULE_4__["Measure"](invalidMinX, invalidMinY, invalidMaxX - invalidMinX + 1, invalidMaxY - invalidMinY + 1);
         }
         else {
             // Compute intersection
-            var maxX = Math.ceil(Math.max(this._clearRectangle.left + this._clearRectangle.width - 1, clearMaxX));
-            var maxY = Math.ceil(Math.max(this._clearRectangle.top + this._clearRectangle.height - 1, clearMaxY));
-            this._clearRectangle.left = Math.floor(Math.min(this._clearRectangle.left, clearMinX));
-            this._clearRectangle.top = Math.floor(Math.min(this._clearRectangle.top, clearMinY));
-            this._clearRectangle.width = maxX - this._clearRectangle.left + 1;
-            this._clearRectangle.height = maxY - this._clearRectangle.top + 1;
-            maxX = Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width - 1, maxX);
-            maxY = Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height - 1, maxY);
-            this._invalidatedRectangle.left = Math.min(this._invalidatedRectangle.left, minX);
-            this._invalidatedRectangle.top = Math.min(this._invalidatedRectangle.top, minY);
+            var maxX = Math.ceil(Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width - 1, invalidMaxX));
+            var maxY = Math.ceil(Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height - 1, invalidMaxY));
+            this._invalidatedRectangle.left = Math.floor(Math.min(this._invalidatedRectangle.left, invalidMinX));
+            this._invalidatedRectangle.top = Math.floor(Math.min(this._invalidatedRectangle.top, invalidMinY));
             this._invalidatedRectangle.width = maxX - this._invalidatedRectangle.left + 1;
             this._invalidatedRectangle.height = maxY - this._invalidatedRectangle.top + 1;
         }
@@ -1016,7 +1005,7 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
                 this._rootContainer._markAllAsDirty();
             }
         }
-        this.invalidateRect(0, 0, textureSize.width - 1, textureSize.height - 1, 0, 0, textureSize.width - 1, textureSize.height - 1);
+        this.invalidateRect(0, 0, textureSize.width - 1, textureSize.height - 1);
     };
     /** @hidden */
     AdvancedDynamicTexture.prototype._getGlobalViewport = function (scene) {
@@ -1096,8 +1085,8 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
         this.onEndLayoutObservable.notifyObservers(this);
         this._isDirty = false; // Restoring the dirty state that could have been set by controls during layout processing
         // Clear
-        if (this._clearRectangle) {
-            this._clearMeasure.copyFrom(this._clearRectangle);
+        if (this._invalidatedRectangle) {
+            this._clearMeasure.copyFrom(this._invalidatedRectangle);
         }
         else {
             this._clearMeasure.copyFromFloats(0, 0, renderWidth, renderHeight);
@@ -1113,7 +1102,6 @@ var AdvancedDynamicTexture = /** @class */ (function (_super) {
         this.onBeginRenderObservable.notifyObservers(this);
         this._rootContainer._render(context, this._invalidatedRectangle);
         this.onEndRenderObservable.notifyObservers(this);
-        this._clearRectangle = null;
         this._invalidatedRectangle = null;
     };
     /** @hidden */
@@ -3511,11 +3499,11 @@ var Container = /** @class */ (function (_super) {
     };
     /** @hidden */
     Container.prototype._layout = function (parentMeasure, context) {
-        if (!this.isVisible || this.notRenderable) {
+        if (!this.isDirty && (!this.isVisible || this.notRenderable)) {
             return false;
         }
         if (this._isDirty) {
-            this._tempCurrentMeasure.copyFrom(this._currentMeasure);
+            this._currentMeasure.transformToRef(this._transformMatrix, this._prevCurrentMeasureTransformedIntoGlobalSpace);
         }
         var rebuildCount = 0;
         context.save();
@@ -3560,7 +3548,7 @@ var Container = /** @class */ (function (_super) {
         }
         context.restore();
         if (this._isDirty) {
-            this.invalidateRect(Math.min(this._currentMeasure.left, this._tempCurrentMeasure.left), Math.min(this._currentMeasure.top, this._tempCurrentMeasure.top), Math.max(this._currentMeasure.left + this._currentMeasure.width, this._tempCurrentMeasure.left + this._tempCurrentMeasure.width) - 1, Math.max(this._currentMeasure.top + this._currentMeasure.height, this._tempCurrentMeasure.top + this._tempCurrentMeasure.height) - 1);
+            this.invalidateRect();
             this._isDirty = false;
         }
         return true;
@@ -3579,7 +3567,7 @@ var Container = /** @class */ (function (_super) {
             // Only redraw parts of the screen that are invalidated
             if (invalidatedRectangle) {
                 if (!child._intersectsRect(invalidatedRectangle)) {
-                    // continue;
+                    continue;
                 }
             }
             child._render(context, invalidatedRectangle);
@@ -3666,7 +3654,6 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-
 /**
  * Root class used for all 2D controls
  * @see http://doc.babylonjs.com/how_to/gui#controls
@@ -3707,7 +3694,7 @@ var Control = /** @class */ (function () {
         /** @hidden */
         this._tempParentMeasure = _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"].Empty();
         /** @hidden */
-        this._tempCurrentMeasure = _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"].Empty();
+        this._prevCurrentMeasureTransformedIntoGlobalSpace = _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"].Empty();
         /** @hidden */
         this._cachedParentMeasure = _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"].Empty();
         this._paddingLeft = new _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__["ValueAndUnit"](0);
@@ -3723,6 +3710,7 @@ var Control = /** @class */ (function () {
         this._rotation = 0;
         this._transformCenterX = 0.5;
         this._transformCenterY = 0.5;
+        /** @hidden */
         this._transformMatrix = _math2D__WEBPACK_IMPORTED_MODULE_3__["Matrix2D"].Identity();
         /** @hidden */
         this._invertTransformMatrix = _math2D__WEBPACK_IMPORTED_MODULE_3__["Matrix2D"].Identity();
@@ -3805,6 +3793,7 @@ var Control = /** @class */ (function () {
          * An event triggered after the control was drawn
          */
         this.onAfterDrawObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
+        this._tmpMeasureA = new _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"](0, 0, 0, 0);
     }
     Object.defineProperty(Control.prototype, "shadowOffsetX", {
         /** Gets or sets a value indicating the offset to apply on X axis to render the shadow */
@@ -3948,7 +3937,6 @@ var Control = /** @class */ (function () {
                 return;
             }
             this._scaleX = value;
-            this._transform();
             this._markAsDirty();
             this._markMatrixAsDirty();
         },
@@ -3967,7 +3955,6 @@ var Control = /** @class */ (function () {
                 return;
             }
             this._scaleY = value;
-            this._transform();
             this._markAsDirty();
             this._markMatrixAsDirty();
         },
@@ -4753,35 +4740,32 @@ var Control = /** @class */ (function () {
     };
     /** @hidden */
     Control.prototype._intersectsRect = function (rect) {
-        if (this._currentMeasure.left >= rect.left + rect.width) {
+        // Rotate the control's current measure into local space and check if it intersects the passed in rectangle
+        this._currentMeasure.transformToRef(this._transformMatrix, this._tmpMeasureA);
+        if (this._tmpMeasureA.left >= rect.left + rect.width) {
             return false;
         }
-        if (this._currentMeasure.top >= rect.top + rect.height) {
+        if (this._tmpMeasureA.top >= rect.top + rect.height) {
             return false;
         }
-        if (this._currentMeasure.left + this._currentMeasure.width <= rect.left) {
+        if (this._tmpMeasureA.left + this._tmpMeasureA.width <= rect.left) {
             return false;
         }
-        if (this._currentMeasure.top + this._currentMeasure.height <= rect.top) {
+        if (this._tmpMeasureA.top + this._tmpMeasureA.height <= rect.top) {
             return false;
         }
         return true;
     };
     /** @hidden */
-    Control.prototype.invalidateRect = function (left, top, right, bottom) {
+    Control.prototype.invalidateRect = function () {
+        this._transform();
         if (this.host && this.host.useInvalidateRectOptimization) {
-            // Compute AABB of transformed container box (eg. to handle rotation and scaling)
-            var rectanglePoints = babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Polygon"].Rectangle(left, top, right, bottom);
-            var min = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Vector2"](Number.MAX_VALUE, Number.MAX_VALUE);
-            var max = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
-            for (var i = 0; i < 4; i++) {
-                this._transformMatrix.transformCoordinates(rectanglePoints[i].x, rectanglePoints[i].y, rectanglePoints[i]);
-                min.x = Math.min(min.x, rectanglePoints[i].x);
-                min.y = Math.min(min.y, rectanglePoints[i].y);
-                max.x = Math.max(max.x, rectanglePoints[i].x);
-                max.y = Math.max(max.y, rectanglePoints[i].y);
-            }
-            this.host.invalidateRect(min.x, min.y, max.x, max.y, left, top, right, bottom);
+            // Rotate by transform to get the measure transformed to global space
+            this._currentMeasure.transformToRef(this._transformMatrix, this._tmpMeasureA);
+            // get the boudning box of the current measure and last frames measure in global space and invalidate it
+            // the previous measure is used to properly clear a control that is scaled down
+            _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"].CombineToRef(this._tmpMeasureA, this._prevCurrentMeasureTransformedIntoGlobalSpace, this._tmpMeasureA);
+            this.host.invalidateRect(Math.floor(this._tmpMeasureA.left), Math.floor(this._tmpMeasureA.top), Math.ceil(this._tmpMeasureA.left + this._tmpMeasureA.width), Math.ceil(this._tmpMeasureA.top + this._tmpMeasureA.height));
         }
     };
     /** @hidden */
@@ -4876,11 +4860,11 @@ var Control = /** @class */ (function () {
     };
     /** @hidden */
     Control.prototype._layout = function (parentMeasure, context) {
-        if (!this.isVisible || this.notRenderable) {
+        if (!this.isDirty && (!this.isVisible || this.notRenderable)) {
             return false;
         }
         if (this._isDirty || !this._cachedParentMeasure.isEqualsTo(parentMeasure)) {
-            this._tempCurrentMeasure.copyFrom(this._currentMeasure);
+            this._currentMeasure.transformToRef(this._transformMatrix, this._prevCurrentMeasureTransformedIntoGlobalSpace);
             context.save();
             this._applyStates(context);
             var rebuildCount = 0;
@@ -4893,7 +4877,7 @@ var Control = /** @class */ (function () {
                 babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Layout cycle detected in GUI (Control name=" + this.name + ", uniqueId=" + this.uniqueId + ")");
             }
             context.restore();
-            this.invalidateRect(Math.min(this._currentMeasure.left, this._tempCurrentMeasure.left), Math.min(this._currentMeasure.top, this._tempCurrentMeasure.top), Math.max(this._currentMeasure.left + this._currentMeasure.width, this._tempCurrentMeasure.left + this._tempCurrentMeasure.width), Math.max(this._currentMeasure.top + this._currentMeasure.height, this._tempCurrentMeasure.top + this._tempCurrentMeasure.height));
+            this.invalidateRect();
             this._evaluateClippingState(parentMeasure);
         }
         this._wasDirty = this._isDirty;
@@ -5047,12 +5031,15 @@ var Control = /** @class */ (function () {
         context.beginPath();
         Control._ClipMeasure.copyFrom(this._currentMeasure);
         if (invalidatedRectangle) {
-            var right = Math.min(invalidatedRectangle.left + invalidatedRectangle.width, this._currentMeasure.left + this._currentMeasure.width);
-            var bottom = Math.min(invalidatedRectangle.top + invalidatedRectangle.height, this._currentMeasure.top + this._currentMeasure.height);
-            Control._ClipMeasure.left = Math.max(invalidatedRectangle.left, this._currentMeasure.left);
-            Control._ClipMeasure.top = Math.max(invalidatedRectangle.top, this._currentMeasure.top);
-            Control._ClipMeasure.width = right - Control._ClipMeasure.left;
-            Control._ClipMeasure.height = bottom - Control._ClipMeasure.top;
+            // Rotate the invalidated rect into the control's space
+            invalidatedRectangle.transformToRef(this._invertTransformMatrix, this._tmpMeasureA);
+            // Get the intersection of the rect in context space and the current context
+            var intersection = new _measure__WEBPACK_IMPORTED_MODULE_2__["Measure"](0, 0, 0, 0);
+            intersection.left = Math.max(this._tmpMeasureA.left, this._currentMeasure.left);
+            intersection.top = Math.max(this._tmpMeasureA.top, this._currentMeasure.top);
+            intersection.width = Math.min(this._tmpMeasureA.left + this._tmpMeasureA.width, this._currentMeasure.left + this._currentMeasure.width) - intersection.left;
+            intersection.height = Math.min(this._tmpMeasureA.top + this._tmpMeasureA.height, this._currentMeasure.top + this._currentMeasure.height) - intersection.top;
+            Control._ClipMeasure.copyFrom(intersection);
         }
         if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
             var shadowOffsetX = this.shadowOffsetX;
@@ -12115,6 +12102,9 @@ var Matrix2D = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Measure", function() { return Measure; });
+/* harmony import */ var babylonjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs */ "babylonjs/Misc/observable");
+/* harmony import */ var babylonjs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs__WEBPACK_IMPORTED_MODULE_0__);
+
 /**
  * Class used to store 2D control sizes
  */
@@ -12164,6 +12154,43 @@ var Measure = /** @class */ (function () {
         this.height = height;
     };
     /**
+     * Computes the axis aligned bounding box measure for two given measures
+     * @param a Input measure
+     * @param b Input measure
+     * @param result the resulting bounding measure
+     */
+    Measure.CombineToRef = function (a, b, result) {
+        var left = Math.min(a.left, b.left);
+        var top = Math.min(a.top, b.top);
+        var right = Math.max(a.left + a.width, b.left + b.width);
+        var bottom = Math.max(a.top + a.height, b.top + b.height);
+        result.left = left;
+        result.top = top;
+        result.width = right - left;
+        result.height = bottom - top;
+    };
+    /**
+     * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+     * @param transform the matrix to transform the measure before computing the AABB
+     * @param result the resulting AABB
+     */
+    Measure.prototype.transformToRef = function (transform, result) {
+        var rectanglePoints = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Polygon"].Rectangle(this.left, this.top, this.left + this.width, this.top + this.height);
+        var min = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector2"](Number.MAX_VALUE, Number.MAX_VALUE);
+        var max = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
+        for (var i = 0; i < 4; i++) {
+            transform.transformCoordinates(rectanglePoints[i].x, rectanglePoints[i].y, rectanglePoints[i]);
+            min.x = Math.floor(Math.min(min.x, rectanglePoints[i].x));
+            min.y = Math.floor(Math.min(min.y, rectanglePoints[i].y));
+            max.x = Math.ceil(Math.max(max.x, rectanglePoints[i].x));
+            max.y = Math.ceil(Math.max(max.y, rectanglePoints[i].y));
+        }
+        result.left = min.x;
+        result.top = min.y;
+        result.width = max.x - min.x;
+        result.height = max.y - min.y;
+    };
+    /**
      * Check equality between this measure and another one
      * @param other defines the other measures
      * @returns true if both measures are equals

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


+ 273 - 252
dist/preview release/gui/babylon.gui.module.d.ts

@@ -117,7 +117,122 @@ declare module "babylonjs-gui/2D/style" {
         dispose(): void;
     }
 }
+declare module "babylonjs-gui/2D/math2D" {
+    import { Nullable } from "babylonjs/types";
+    import { Vector2 } from "babylonjs/Maths/math";
+    /**
+     * Class used to transport Vector2 information for pointer events
+     */
+    export class Vector2WithInfo extends Vector2 {
+        /** defines the current mouse button index */
+        buttonIndex: number;
+        /**
+         * Creates a new Vector2WithInfo
+         * @param source defines the vector2 data to transport
+         * @param buttonIndex defines the current mouse button index
+         */
+        constructor(source: Vector2, 
+        /** defines the current mouse button index */
+        buttonIndex?: number);
+    }
+    /** Class used to provide 2D matrix features */
+    export class Matrix2D {
+        /** Gets the internal array of 6 floats used to store matrix data */
+        m: Float32Array;
+        /**
+         * Creates a new matrix
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         */
+        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
+        /**
+         * Fills the matrix from direct values
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         * @returns the current modified matrix
+         */
+        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
+        /**
+         * Gets matrix determinant
+         * @returns the determinant
+         */
+        determinant(): number;
+        /**
+         * Inverses the matrix and stores it in a target matrix
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        invertToRef(result: Matrix2D): Matrix2D;
+        /**
+         * Multiplies the current matrix with another one
+         * @param other defines the second operand
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
+        /**
+         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+         * @param x defines the x coordinate to transform
+         * @param y defines the x coordinate to transform
+         * @param result defines the target vector2
+         * @returns the current matrix
+         */
+        transformCoordinates(x: number, y: number, result: Vector2): Matrix2D;
+        /**
+         * Creates an identity matrix
+         * @returns a new matrix
+         */
+        static Identity(): Matrix2D;
+        /**
+         * Creates a translation matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the translation
+         * @param y defines the y coordinate of the translation
+         * @param result defines the target matrix
+         */
+        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a scaling matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the scaling
+         * @param y defines the y coordinate of the scaling
+         * @param result defines the target matrix
+         */
+        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a rotation matrix and stores it in a target matrix
+         * @param angle defines the rotation angle
+         * @param result defines the target matrix
+         */
+        static RotationToRef(angle: number, result: Matrix2D): void;
+        private static _TempPreTranslationMatrix;
+        private static _TempPostTranslationMatrix;
+        private static _TempRotationMatrix;
+        private static _TempScalingMatrix;
+        private static _TempCompose0;
+        private static _TempCompose1;
+        private static _TempCompose2;
+        /**
+         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
+         * @param tx defines the x coordinate of the translation
+         * @param ty defines the y coordinate of the translation
+         * @param angle defines the rotation angle
+         * @param scaleX defines the x coordinate of the scaling
+         * @param scaleY defines the y coordinate of the scaling
+         * @param parentMatrix defines the parent matrix to multiply by (can be null)
+         * @param result defines the target matrix
+         */
+        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>, result: Matrix2D): void;
+    }
+}
 declare module "babylonjs-gui/2D/measure" {
+    import { Matrix2D } from "babylonjs-gui/2D/math2D";
     /**
      * Class used to store 2D control sizes
      */
@@ -160,6 +275,19 @@ declare module "babylonjs-gui/2D/measure" {
          */
         copyFromFloats(left: number, top: number, width: number, height: number): void;
         /**
+         * Computes the axis aligned bounding box measure for two given measures
+         * @param a Input measure
+         * @param b Input measure
+         * @param result the resulting bounding measure
+         */
+        static CombineToRef(a: Measure, b: Measure, result: Measure): void;
+        /**
+         * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+         * @param transform the matrix to transform the measure before computing the AABB
+         * @param result the resulting AABB
+         */
+        transformToRef(transform: Matrix2D, result: Measure): void;
+        /**
          * Check equality between this measure and another one
          * @param other defines the other measures
          * @returns true if both measures are equals
@@ -373,20 +501,15 @@ declare module "babylonjs-gui/2D/advancedDynamicTexture" {
          * Gets or sets a boolean indicating if the InvalidateRect optimization should be turned on
          */
         useInvalidateRectOptimization: boolean;
-        private _clearRectangle;
         private _invalidatedRectangle;
         /**
          * Invalidates a rectangle area on the gui texture
-         * @param clearMinX left most position of the rectangle to clear in the texture
-         * @param clearMinY top most position of the rectangle to clear in the texture
-         * @param clearMaxX right most position of the rectangle to clear in the texture
-         * @param clearMaxY bottom most position of the rectangle to clear in the texture
-         * @param minX left most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param minY top most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxX right most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxY bottom most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
+         * @param invalidMinX left most position of the rectangle to invalidate in the texture
+         * @param invalidMinY top most position of the rectangle to invalidate in the texture
+         * @param invalidMaxX right most position of the rectangle to invalidate in the texture
+         * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
          */
-        invalidateRect(clearMinX: number, clearMinY: number, clearMaxX: number, clearMaxY: number, minX: number, minY: number, maxX: number, maxY: number): void;
+        invalidateRect(invalidMinX: number, invalidMinY: number, invalidMaxX: number, invalidMaxY: number): void;
         /**
         * Marks the texture as dirty forcing a complete update
         */
@@ -491,120 +614,6 @@ declare module "babylonjs-gui/2D/advancedDynamicTexture" {
         static CreateFullscreenUI(name: string, foreground?: boolean, scene?: Nullable<Scene>, sampling?: number): AdvancedDynamicTexture;
     }
 }
-declare module "babylonjs-gui/2D/math2D" {
-    import { Nullable } from "babylonjs/types";
-    import { Vector2 } from "babylonjs/Maths/math";
-    /**
-     * Class used to transport Vector2 information for pointer events
-     */
-    export class Vector2WithInfo extends Vector2 {
-        /** defines the current mouse button index */
-        buttonIndex: number;
-        /**
-         * Creates a new Vector2WithInfo
-         * @param source defines the vector2 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */
-        constructor(source: Vector2, 
-        /** defines the current mouse button index */
-        buttonIndex?: number);
-    }
-    /** Class used to provide 2D matrix features */
-    export class Matrix2D {
-        /** Gets the internal array of 6 floats used to store matrix data */
-        m: Float32Array;
-        /**
-         * Creates a new matrix
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         */
-        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
-        /**
-         * Fills the matrix from direct values
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         * @returns the current modified matrix
-         */
-        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
-        /**
-         * Gets matrix determinant
-         * @returns the determinant
-         */
-        determinant(): number;
-        /**
-         * Inverses the matrix and stores it in a target matrix
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        invertToRef(result: Matrix2D): Matrix2D;
-        /**
-         * Multiplies the current matrix with another one
-         * @param other defines the second operand
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
-        /**
-         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
-         * @param x defines the x coordinate to transform
-         * @param y defines the x coordinate to transform
-         * @param result defines the target vector2
-         * @returns the current matrix
-         */
-        transformCoordinates(x: number, y: number, result: Vector2): Matrix2D;
-        /**
-         * Creates an identity matrix
-         * @returns a new matrix
-         */
-        static Identity(): Matrix2D;
-        /**
-         * Creates a translation matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the translation
-         * @param y defines the y coordinate of the translation
-         * @param result defines the target matrix
-         */
-        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a scaling matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the scaling
-         * @param y defines the y coordinate of the scaling
-         * @param result defines the target matrix
-         */
-        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a rotation matrix and stores it in a target matrix
-         * @param angle defines the rotation angle
-         * @param result defines the target matrix
-         */
-        static RotationToRef(angle: number, result: Matrix2D): void;
-        private static _TempPreTranslationMatrix;
-        private static _TempPostTranslationMatrix;
-        private static _TempRotationMatrix;
-        private static _TempScalingMatrix;
-        private static _TempCompose0;
-        private static _TempCompose1;
-        private static _TempCompose2;
-        /**
-         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
-         * @param tx defines the x coordinate of the translation
-         * @param ty defines the y coordinate of the translation
-         * @param angle defines the rotation angle
-         * @param scaleX defines the x coordinate of the scaling
-         * @param scaleY defines the y coordinate of the scaling
-         * @param parentMatrix defines the parent matrix to multiply by (can be null)
-         * @param result defines the target matrix
-         */
-        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>, result: Matrix2D): void;
-    }
-}
 declare module "babylonjs-gui/2D/controls/control" {
     import { Nullable } from "babylonjs/types";
     import { Observable } from "babylonjs/Misc/observable";
@@ -666,7 +675,7 @@ declare module "babylonjs-gui/2D/controls/control" {
         /** @hidden */
         _tempParentMeasure: Measure;
         /** @hidden */
-        _tempCurrentMeasure: Measure;
+        _prevCurrentMeasureTransformedIntoGlobalSpace: Measure;
         /** @hidden */
         protected _cachedParentMeasure: Measure;
         private _paddingLeft;
@@ -682,7 +691,8 @@ declare module "babylonjs-gui/2D/controls/control" {
         private _rotation;
         private _transformCenterX;
         private _transformCenterY;
-        private _transformMatrix;
+        /** @hidden */
+        _transformMatrix: Matrix2D;
         /** @hidden */
         protected _invertTransformMatrix: Matrix2D;
         /** @hidden */
@@ -1051,7 +1061,7 @@ declare module "babylonjs-gui/2D/controls/control" {
         /** @hidden */
         _intersectsRect(rect: Measure): boolean;
         /** @hidden */
-        protected invalidateRect(left: number, top: number, right: number, bottom: number): void;
+        protected invalidateRect(): void;
         /** @hidden */
         _markAsDirty(force?: boolean): void;
         /** @hidden */
@@ -1082,6 +1092,7 @@ declare module "babylonjs-gui/2D/controls/control" {
         /** @hidden */
         protected _clipForChildren(context: CanvasRenderingContext2D): void;
         private static _ClipMeasure;
+        private _tmpMeasureA;
         private _clip;
         /** @hidden */
         _render(context: CanvasRenderingContext2D, invalidatedRectangle?: Nullable<Measure>): boolean;
@@ -3940,6 +3951,118 @@ declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
     /**
+     * Class used to transport BABYLON.Vector2 information for pointer events
+     */
+    export class Vector2WithInfo extends BABYLON.Vector2 {
+        /** defines the current mouse button index */
+        buttonIndex: number;
+        /**
+         * Creates a new Vector2WithInfo
+         * @param source defines the vector2 data to transport
+         * @param buttonIndex defines the current mouse button index
+         */
+        constructor(source: BABYLON.Vector2, 
+        /** defines the current mouse button index */
+        buttonIndex?: number);
+    }
+    /** Class used to provide 2D matrix features */
+    export class Matrix2D {
+        /** Gets the internal array of 6 floats used to store matrix data */
+        m: Float32Array;
+        /**
+         * Creates a new matrix
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         */
+        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
+        /**
+         * Fills the matrix from direct values
+         * @param m00 defines value for (0, 0)
+         * @param m01 defines value for (0, 1)
+         * @param m10 defines value for (1, 0)
+         * @param m11 defines value for (1, 1)
+         * @param m20 defines value for (2, 0)
+         * @param m21 defines value for (2, 1)
+         * @returns the current modified matrix
+         */
+        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
+        /**
+         * Gets matrix determinant
+         * @returns the determinant
+         */
+        determinant(): number;
+        /**
+         * Inverses the matrix and stores it in a target matrix
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        invertToRef(result: Matrix2D): Matrix2D;
+        /**
+         * Multiplies the current matrix with another one
+         * @param other defines the second operand
+         * @param result defines the target matrix
+         * @returns the current matrix
+         */
+        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
+        /**
+         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+         * @param x defines the x coordinate to transform
+         * @param y defines the x coordinate to transform
+         * @param result defines the target vector2
+         * @returns the current matrix
+         */
+        transformCoordinates(x: number, y: number, result: BABYLON.Vector2): Matrix2D;
+        /**
+         * Creates an identity matrix
+         * @returns a new matrix
+         */
+        static Identity(): Matrix2D;
+        /**
+         * Creates a translation matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the translation
+         * @param y defines the y coordinate of the translation
+         * @param result defines the target matrix
+         */
+        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a scaling matrix and stores it in a target matrix
+         * @param x defines the x coordinate of the scaling
+         * @param y defines the y coordinate of the scaling
+         * @param result defines the target matrix
+         */
+        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
+        /**
+         * Creates a rotation matrix and stores it in a target matrix
+         * @param angle defines the rotation angle
+         * @param result defines the target matrix
+         */
+        static RotationToRef(angle: number, result: Matrix2D): void;
+        private static _TempPreTranslationMatrix;
+        private static _TempPostTranslationMatrix;
+        private static _TempRotationMatrix;
+        private static _TempScalingMatrix;
+        private static _TempCompose0;
+        private static _TempCompose1;
+        private static _TempCompose2;
+        /**
+         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
+         * @param tx defines the x coordinate of the translation
+         * @param ty defines the y coordinate of the translation
+         * @param angle defines the rotation angle
+         * @param scaleX defines the x coordinate of the scaling
+         * @param scaleY defines the y coordinate of the scaling
+         * @param parentMatrix defines the parent matrix to multiply by (can be null)
+         * @param result defines the target matrix
+         */
+        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: BABYLON.Nullable<Matrix2D>, result: Matrix2D): void;
+    }
+}
+declare module BABYLON.GUI {
+    /**
      * Class used to store 2D control sizes
      */
     export class Measure {
@@ -3981,6 +4104,19 @@ declare module BABYLON.GUI {
          */
         copyFromFloats(left: number, top: number, width: number, height: number): void;
         /**
+         * Computes the axis aligned bounding box measure for two given measures
+         * @param a Input measure
+         * @param b Input measure
+         * @param result the resulting bounding measure
+         */
+        static CombineToRef(a: Measure, b: Measure, result: Measure): void;
+        /**
+         * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+         * @param transform the matrix to transform the measure before computing the AABB
+         * @param result the resulting AABB
+         */
+        transformToRef(transform: Matrix2D, result: Measure): void;
+        /**
          * Check equality between this measure and another one
          * @param other defines the other measures
          * @returns true if both measures are equals
@@ -4183,20 +4319,15 @@ declare module BABYLON.GUI {
          * Gets or sets a boolean indicating if the InvalidateRect optimization should be turned on
          */
         useInvalidateRectOptimization: boolean;
-        private _clearRectangle;
         private _invalidatedRectangle;
         /**
          * Invalidates a rectangle area on the gui texture
-         * @param clearMinX left most position of the rectangle to clear in the texture
-         * @param clearMinY top most position of the rectangle to clear in the texture
-         * @param clearMaxX right most position of the rectangle to clear in the texture
-         * @param clearMaxY bottom most position of the rectangle to clear in the texture
-         * @param minX left most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param minY top most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxX right most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-         * @param maxY bottom most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
+         * @param invalidMinX left most position of the rectangle to invalidate in the texture
+         * @param invalidMinY top most position of the rectangle to invalidate in the texture
+         * @param invalidMaxX right most position of the rectangle to invalidate in the texture
+         * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
          */
-        invalidateRect(clearMinX: number, clearMinY: number, clearMaxX: number, clearMaxY: number, minX: number, minY: number, maxX: number, maxY: number): void;
+        invalidateRect(invalidMinX: number, invalidMinY: number, invalidMaxX: number, invalidMaxY: number): void;
         /**
         * Marks the texture as dirty forcing a complete update
         */
@@ -4303,118 +4434,6 @@ declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
     /**
-     * Class used to transport BABYLON.Vector2 information for pointer events
-     */
-    export class Vector2WithInfo extends BABYLON.Vector2 {
-        /** defines the current mouse button index */
-        buttonIndex: number;
-        /**
-         * Creates a new Vector2WithInfo
-         * @param source defines the vector2 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */
-        constructor(source: BABYLON.Vector2, 
-        /** defines the current mouse button index */
-        buttonIndex?: number);
-    }
-    /** Class used to provide 2D matrix features */
-    export class Matrix2D {
-        /** Gets the internal array of 6 floats used to store matrix data */
-        m: Float32Array;
-        /**
-         * Creates a new matrix
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         */
-        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number);
-        /**
-         * Fills the matrix from direct values
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         * @returns the current modified matrix
-         */
-        fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D;
-        /**
-         * Gets matrix determinant
-         * @returns the determinant
-         */
-        determinant(): number;
-        /**
-         * Inverses the matrix and stores it in a target matrix
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        invertToRef(result: Matrix2D): Matrix2D;
-        /**
-         * Multiplies the current matrix with another one
-         * @param other defines the second operand
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D;
-        /**
-         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
-         * @param x defines the x coordinate to transform
-         * @param y defines the x coordinate to transform
-         * @param result defines the target vector2
-         * @returns the current matrix
-         */
-        transformCoordinates(x: number, y: number, result: BABYLON.Vector2): Matrix2D;
-        /**
-         * Creates an identity matrix
-         * @returns a new matrix
-         */
-        static Identity(): Matrix2D;
-        /**
-         * Creates a translation matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the translation
-         * @param y defines the y coordinate of the translation
-         * @param result defines the target matrix
-         */
-        static TranslationToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a scaling matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the scaling
-         * @param y defines the y coordinate of the scaling
-         * @param result defines the target matrix
-         */
-        static ScalingToRef(x: number, y: number, result: Matrix2D): void;
-        /**
-         * Creates a rotation matrix and stores it in a target matrix
-         * @param angle defines the rotation angle
-         * @param result defines the target matrix
-         */
-        static RotationToRef(angle: number, result: Matrix2D): void;
-        private static _TempPreTranslationMatrix;
-        private static _TempPostTranslationMatrix;
-        private static _TempRotationMatrix;
-        private static _TempScalingMatrix;
-        private static _TempCompose0;
-        private static _TempCompose1;
-        private static _TempCompose2;
-        /**
-         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix
-         * @param tx defines the x coordinate of the translation
-         * @param ty defines the y coordinate of the translation
-         * @param angle defines the rotation angle
-         * @param scaleX defines the x coordinate of the scaling
-         * @param scaleY defines the y coordinate of the scaling
-         * @param parentMatrix defines the parent matrix to multiply by (can be null)
-         * @param result defines the target matrix
-         */
-        static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: BABYLON.Nullable<Matrix2D>, result: Matrix2D): void;
-    }
-}
-declare module BABYLON.GUI {
-    /**
      * Root class used for all 2D controls
      * @see http://doc.babylonjs.com/how_to/gui#controls
      */
@@ -4463,7 +4482,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         _tempParentMeasure: Measure;
         /** @hidden */
-        _tempCurrentMeasure: Measure;
+        _prevCurrentMeasureTransformedIntoGlobalSpace: Measure;
         /** @hidden */
         protected _cachedParentMeasure: Measure;
         private _paddingLeft;
@@ -4479,7 +4498,8 @@ declare module BABYLON.GUI {
         private _rotation;
         private _transformCenterX;
         private _transformCenterY;
-        private _transformMatrix;
+        /** @hidden */
+        _transformMatrix: Matrix2D;
         /** @hidden */
         protected _invertTransformMatrix: Matrix2D;
         /** @hidden */
@@ -4848,7 +4868,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         _intersectsRect(rect: Measure): boolean;
         /** @hidden */
-        protected invalidateRect(left: number, top: number, right: number, bottom: number): void;
+        protected invalidateRect(): void;
         /** @hidden */
         _markAsDirty(force?: boolean): void;
         /** @hidden */
@@ -4879,6 +4899,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         protected _clipForChildren(context: CanvasRenderingContext2D): void;
         private static _ClipMeasure;
+        private _tmpMeasureA;
         private _clip;
         /** @hidden */
         _render(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): boolean;

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 47 - 31
dist/preview release/viewer/babylon.viewer.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -124,7 +124,7 @@
 - Gizmo scaling not consistent when camera is parented ([TrevorDev](https://github.com/TrevorDev))
 - Context loss causing unexpected results with dynamic textures, geometries with the same name and reflectionTextures ([TrevorDev](https://github.com/TrevorDev))
 - CreateScreenshotUsingRenderTarget stretches mirror textures when setting both width and height ([TrevorDev](https://github.com/TrevorDev))
-- VR helper only updating vr cameras position when entering vr, rotation was missing ([TrevorDev](https://github.com/TrevorDev))
+- VR helper only updating vr cameras position when entering vr, rotation was missing, laser distance stopped working ([TrevorDev](https://github.com/TrevorDev))
 - Fix VR controllers after gltfLoader transformNode change ([TrevorDev](https://github.com/TrevorDev))
 - Bounding Box fixedDragMeshScreenSize stopped working and allow rotating through bounding box ([TrevorDev](https://github.com/TrevorDev))
 - VR helper would rotate non vr camera while in VR ([TrevorDev](https://github.com/TrevorDev))
@@ -143,6 +143,7 @@
 - Updated comment in TransformNode.rotationQuaternion to include undefined as one of the potential return values ([nathankmiller](https://github.com/nathankmiller))
 - CannonJS ignores connectedPivot joint parameter ([TrevorDev](https://github.com/TrevorDev))
 - Fix case sensitive paths ([mrdunk](https://github.com))
+- Fix more case sensitive paths ([mrdunk](https://github.com))
 - Attaching a BoundingBoxGizmo on a child should not remove its parent ([TrevorDev](https://github.com/TrevorDev)))
 - AmmoJS fix include issue caused after modules update and use world contact point to be consistent with oimo and cannon ([TrevorDev](https://github.com/TrevorDev)))
 

+ 3 - 3
materialsLibrary/test/addfur.js

@@ -2,8 +2,8 @@ window.prepareFur = function() {
 	var shells = 30;
 	var meshes = [];
 	
-	var diffuseTexture = new BABYLON.Texture("/playground/textures/leopard_fur.JPG", scene);
-	var heightTexture = new BABYLON.Texture("/playground/textures/speckles.jpg", scene);
+	var diffuseTexture = new BABYLON.Texture("/Playground/textures/leopard_fur.JPG", scene);
+	var heightTexture = new BABYLON.Texture("/Playground/textures/speckles.jpg", scene);
 	var furTexture = BABYLON.FurMaterial.GenerateTexture("furTexture", scene);
 	
 	var fur = new BABYLON.FurMaterial("fur", scene);
@@ -132,4 +132,4 @@ window.prepareFur = function() {
 			configureFur(mesh);
 		}
 	};
-};
+};

+ 21 - 0
src/Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts

@@ -1,6 +1,27 @@
 import { Nullable } from "../../types";
 import { ArcRotateCamera } from "../../Cameras/arcRotateCamera";
 import { ICameraInput, CameraInputTypes } from "../../Cameras/cameraInputsManager";
+import { ArcRotateCameraInputsManager } from "../../Cameras/arcRotateCameraInputsManager";
+
+// Module augmentation to abstract orientation inputs from camera.
+declare module "../../Cameras/arcRotateCameraInputsManager" {
+    export interface ArcRotateCameraInputsManager {
+        /**
+         * Add orientation input support to the input manager.
+         * @returns the current input manager
+         */
+        addVRDeviceOrientation(): ArcRotateCameraInputsManager;
+    }
+}
+
+/**
+ * Add orientation input support to the input manager.
+ * @returns the current input manager
+ */
+ArcRotateCameraInputsManager.prototype.addVRDeviceOrientation = function(): ArcRotateCameraInputsManager {
+    this.add(new ArcRotateCameraVRDeviceOrientationInput());
+    return this;
+};
 
 /**
  * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.

+ 22 - 0
src/Cameras/Inputs/freeCameraDeviceOrientationInput.ts

@@ -3,6 +3,28 @@ import { ICameraInput, CameraInputTypes } from "../../Cameras/cameraInputsManage
 import { FreeCamera } from "../../Cameras/freeCamera";
 import { Quaternion } from "../../Maths/math";
 import { Tools } from "../../Misc/tools";
+import { FreeCameraInputsManager } from "../../Cameras/freeCameraInputsManager";
+
+// Module augmentation to abstract orientation inputs from camera.
+declare module "../../Cameras/freeCameraInputsManager" {
+    export interface FreeCameraInputsManager {
+        /**
+         * Add orientation input support to the input manager.
+         * @returns the current input manager
+         */
+        addDeviceOrientation(): FreeCameraInputsManager;
+    }
+}
+
+/**
+ * Add orientation input support to the input manager.
+ * @returns the current input manager
+ */
+FreeCameraInputsManager.prototype.addDeviceOrientation = function(): FreeCameraInputsManager {
+    this.add(new FreeCameraDeviceOrientationInput());
+    return this;
+};
+
 /**
  * Takes information about the orientation of the device as reported by the deviceorientation event to orient the camera.
  * Screen rotation is taken into account.

+ 22 - 0
src/Cameras/Inputs/freeCameraVirtualJoystickInput.ts

@@ -3,6 +3,28 @@ import { Nullable } from "../../types";
 import { ICameraInput, CameraInputTypes } from "../../Cameras/cameraInputsManager";
 import { FreeCamera } from "../../Cameras/freeCamera";
 import { Matrix, Vector3 } from "../../Maths/math";
+import { FreeCameraInputsManager } from "../../Cameras/freeCameraInputsManager";
+
+// Module augmentation to abstract virtual joystick from camera.
+declare module "../../Cameras/freeCameraInputsManager" {
+    export interface FreeCameraInputsManager {
+        /**
+         * Add virtual joystick input support to the input manager.
+         * @returns the current input manager
+         */
+        addVirtualJoystick(): FreeCameraInputsManager;
+    }
+}
+
+/**
+* Add virtual joystick input support to the input manager.
+* @returns the current input manager
+*/
+FreeCameraInputsManager.prototype.addVirtualJoystick = function(): FreeCameraInputsManager {
+   this.add(new FreeCameraVirtualJoystickInput());
+   return this;
+};
+
 /**
  * Manage the Virtual Joystick inputs to control the movement of a free camera.
  * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs

+ 4 - 0
src/Cameras/RigModes/index.ts

@@ -0,0 +1,4 @@
+export * from "./stereoscopicAnaglyphRigMode";
+export * from "./stereoscopicRigMode";
+export * from "./vrRigMode";
+export * from "./webVRRigMode";

+ 8 - 0
src/Cameras/RigModes/stereoscopicAnaglyphRigMode.ts

@@ -0,0 +1,8 @@
+import { Camera } from "../camera";
+import { PassPostProcess } from "../../PostProcesses/passPostProcess";
+import { AnaglyphPostProcess } from "../../PostProcesses/anaglyphPostProcess";
+
+Camera._setStereoscopicAnaglyphRigMode = function(camera: Camera) {
+    camera._rigCameras[0]._rigPostProcess = new PassPostProcess(camera.name + "_passthru", 1.0, camera._rigCameras[0]);
+    camera._rigCameras[1]._rigPostProcess = new AnaglyphPostProcess(camera.name + "_anaglyph", 1.0, camera._rigCameras);
+};

+ 10 - 0
src/Cameras/RigModes/stereoscopicRigMode.ts

@@ -0,0 +1,10 @@
+import { Camera } from "../camera";
+import { PassPostProcess } from "../../PostProcesses/passPostProcess";
+import { StereoscopicInterlacePostProcess } from "../../PostProcesses/stereoscopicInterlacePostProcess";
+
+Camera._setStereoscopicRigMode = function(camera: Camera) {
+    var isStereoscopicHoriz = camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
+
+    camera._rigCameras[0]._rigPostProcess = new PassPostProcess(camera.name + "_passthru", 1.0, camera._rigCameras[0]);
+    camera._rigCameras[1]._rigPostProcess = new StereoscopicInterlacePostProcess(camera.name + "_stereoInterlace", camera._rigCameras, isStereoscopicHoriz);
+};

+ 27 - 0
src/Cameras/RigModes/vrRigMode.ts

@@ -0,0 +1,27 @@
+import { Camera } from "../camera";
+import { Matrix, Viewport } from "../../Maths/math";
+import { VRDistortionCorrectionPostProcess } from "../../PostProcesses/vrDistortionCorrectionPostProcess";
+import { VRCameraMetrics } from "../VR/vrCameraMetrics";
+
+Camera._setVRRigMode = function(camera: Camera, rigParams: any) {
+    var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
+
+    camera._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
+    camera._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
+    camera._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
+    camera._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
+    camera._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
+    camera._rigCameras[0].getProjectionMatrix = camera._rigCameras[0]._getVRProjectionMatrix;
+
+    camera._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
+    camera._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
+    camera._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
+    camera._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
+    camera._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
+    camera._rigCameras[1].getProjectionMatrix = camera._rigCameras[1]._getVRProjectionMatrix;
+
+    if (metrics.compensateDistortion) {
+        camera._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", camera._rigCameras[0], false, metrics);
+        camera._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", camera._rigCameras[1], true, metrics);
+    }
+};

+ 38 - 0
src/Cameras/RigModes/webVRRigMode.ts

@@ -0,0 +1,38 @@
+import { Camera } from "../camera";
+import { Matrix, Viewport } from "../../Maths/math";
+
+Camera._setWebVRRigMode = function(camera: Camera, rigParams: any) {
+    if (rigParams.vrDisplay) {
+        var leftEye = rigParams.vrDisplay.getEyeParameters('left');
+        var rightEye = rigParams.vrDisplay.getEyeParameters('right');
+
+        //Left eye
+        camera._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
+        camera._rigCameras[0].setCameraRigParameter("left", true);
+        //leaving this for future reference
+        camera._rigCameras[0].setCameraRigParameter("specs", rigParams.specs);
+        camera._rigCameras[0].setCameraRigParameter("eyeParameters", leftEye);
+        camera._rigCameras[0].setCameraRigParameter("frameData", rigParams.frameData);
+        camera._rigCameras[0].setCameraRigParameter("parentCamera", rigParams.parentCamera);
+        camera._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
+        camera._rigCameras[0].getProjectionMatrix = camera._getWebVRProjectionMatrix;
+        camera._rigCameras[0].parent = camera;
+        camera._rigCameras[0]._getViewMatrix = camera._getWebVRViewMatrix;
+
+        //Right eye
+        camera._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
+        camera._rigCameras[1].setCameraRigParameter('eyeParameters', rightEye);
+        camera._rigCameras[1].setCameraRigParameter("specs", rigParams.specs);
+        camera._rigCameras[1].setCameraRigParameter("frameData", rigParams.frameData);
+        camera._rigCameras[1].setCameraRigParameter("parentCamera", rigParams.parentCamera);
+        camera._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
+        camera._rigCameras[1].getProjectionMatrix = camera._getWebVRProjectionMatrix;
+        camera._rigCameras[1].parent = camera;
+        camera._rigCameras[1]._getViewMatrix = camera._getWebVRViewMatrix;
+
+        if (Camera.UseAlternateWebVRRendering) {
+            camera._rigCameras[1]._skipRendering = true;
+            camera._rigCameras[0]._alternateCamera = camera._rigCameras[1];
+        }
+    }
+};

+ 3 - 0
src/Cameras/Stereoscopic/anaglyphArcRotateCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicAnaglyphRigMode";
+
 Node.AddNodeConstructor("AnaglyphArcRotateCamera", (name, scene, options) => {
     return () => new AnaglyphArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), options.interaxial_distance, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/anaglyphFreeCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicAnaglyphRigMode";
+
 Node.AddNodeConstructor("AnaglyphFreeCamera", (name, scene, options) => {
     return () => new AnaglyphFreeCamera(name, Vector3.Zero(), options.interaxial_distance, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/anaglyphGamepadCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicAnaglyphRigMode";
+
 Node.AddNodeConstructor("AnaglyphGamepadCamera", (name, scene, options) => {
     return () => new AnaglyphGamepadCamera(name, Vector3.Zero(), options.interaxial_distance, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/anaglyphUniversalCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicAnaglyphRigMode";
+
 Node.AddNodeConstructor("AnaglyphUniversalCamera", (name, scene, options) => {
     return () => new AnaglyphUniversalCamera(name, Vector3.Zero(), options.interaxial_distance, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/stereoscopicArcRotateCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicRigMode";
+
 Node.AddNodeConstructor("StereoscopicArcRotateCamera", (name, scene, options) => {
     return () => new StereoscopicArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/stereoscopicFreeCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicRigMode";
+
 Node.AddNodeConstructor("StereoscopicFreeCamera", (name, scene, options) => {
     return () => new StereoscopicFreeCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/stereoscopicGamepadCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicRigMode";
+
 Node.AddNodeConstructor("StereoscopicGamepadCamera", (name, scene, options) => {
     return () => new StereoscopicGamepadCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);
 });

+ 3 - 0
src/Cameras/Stereoscopic/stereoscopicUniversalCamera.ts

@@ -4,6 +4,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/stereoscopicRigMode";
+
 Node.AddNodeConstructor("StereoscopicFreeCamera", (name, scene, options) => {
     return () => new StereoscopicUniversalCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);
 });

+ 5 - 0
src/Cameras/VR/vrDeviceOrientationArcRotateCamera.ts

@@ -5,6 +5,11 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+import "../Inputs/arcRotateCameraVRDeviceOrientationInput";
+
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/vrRigMode";
+
 Node.AddNodeConstructor("VRDeviceOrientationFreeCamera", (name, scene) => {
     return () => new VRDeviceOrientationArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), scene);
 });

+ 3 - 0
src/Cameras/VR/vrDeviceOrientationFreeCamera.ts

@@ -5,6 +5,9 @@ import { Scene } from "../../scene";
 import { Vector3 } from "../../Maths/math";
 import { Node } from "../../node";
 
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/vrRigMode";
+
 Node.AddNodeConstructor("VRDeviceOrientationFreeCamera", (name, scene) => {
     return () => new VRDeviceOrientationFreeCamera(name, Vector3.Zero(), scene);
 });

+ 2 - 2
src/Cameras/VR/vrExperienceHelper.ts

@@ -151,7 +151,7 @@ class VRExperienceHelperGazer implements IDisposable {
     }
 
     /** @hidden */
-    public _updatePointerDistance() {
+    public _updatePointerDistance(distance: number = 100) {
     }
 
     public dispose() {
@@ -1841,7 +1841,7 @@ export class VRExperienceHelper {
             }
 
             // Changing the size of the laser pointer based on the distance from the targetted point
-            gazer._updatePointerDistance();
+            gazer._updatePointerDistance(hit.distance);
         }
         else {
             gazer._updatePointerDistance();

+ 8 - 2
src/Cameras/VR/webVRCamera.ts

@@ -13,6 +13,10 @@ import { Node } from "../../node";
 import { AbstractMesh } from "../../Meshes/abstractMesh";
 import { Ray } from "../../Culling/ray";
 import { HemisphericLight } from "../../Lights/hemisphericLight";
+
+// Side effect import to define the stereoscopic mode.
+import "../RigModes/webVRRigMode";
+
 Node.AddNodeConstructor("WebVRFreeCamera", (name, scene) => {
     return () => new WebVRFreeCamera(name, Vector3.Zero(), scene);
 });
@@ -634,8 +638,9 @@ export class WebVRFreeCamera extends FreeCamera implements PoseControlled {
     /**
      * This function is called by the two RIG cameras.
      * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
+     * @hidden
      */
-    protected _getWebVRViewMatrix(): Matrix {
+    public _getWebVRViewMatrix(): Matrix {
         // Update the parent camera prior to using a child camera to avoid desynchronization
         let parentCamera: WebVRFreeCamera = this._cameraRigParams["parentCamera"];
         parentCamera._updateCache();
@@ -684,7 +689,8 @@ export class WebVRFreeCamera extends FreeCamera implements PoseControlled {
         return this._webvrViewMatrix;
     }
 
-    protected _getWebVRProjectionMatrix(): Matrix {
+    /** @hidden */
+    public _getWebVRProjectionMatrix(): Matrix {
 
         let parentCamera = <WebVRFreeCamera>this.parent;
 

+ 0 - 10
src/Cameras/arcRotateCameraInputsManager.ts

@@ -1,5 +1,4 @@
 import { ArcRotateCamera } from "./arcRotateCamera";
-import { ArcRotateCameraVRDeviceOrientationInput } from "../Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput";
 import { ArcRotateCameraPointersInput } from "../Cameras/Inputs/arcRotateCameraPointersInput";
 import { ArcRotateCameraKeyboardMoveInput } from "../Cameras/Inputs/arcRotateCameraKeyboardMoveInput";
 import { ArcRotateCameraMouseWheelInput } from "../Cameras/Inputs/arcRotateCameraMouseWheelInput";
@@ -45,13 +44,4 @@ export class ArcRotateCameraInputsManager extends CameraInputsManager<ArcRotateC
         this.add(new ArcRotateCameraKeyboardMoveInput());
         return this;
     }
-
-    /**
-     * Add orientation input support to the input manager.
-     * @returns the current input manager
-     */
-    public addVRDeviceOrientation(): ArcRotateCameraInputsManager {
-        this.add(new ArcRotateCameraVRDeviceOrientationInput());
-        return this;
-    }
 }

+ 36 - 75
src/Cameras/camera.ts

@@ -11,16 +11,12 @@ import { Mesh } from "../Meshes/mesh";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Ray } from "../Culling/ray";
 import { ICullable } from "../Culling/boundingInfo";
-import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
-import { PostProcess } from "../PostProcesses/postProcess";
-import { PassPostProcess } from "../PostProcesses/passPostProcess";
-import { AnaglyphPostProcess } from "../PostProcesses/anaglyphPostProcess";
-import { StereoscopicInterlacePostProcess } from "../PostProcesses/stereoscopicInterlacePostProcess";
-import { VRDistortionCorrectionPostProcess } from "../PostProcesses/vrDistortionCorrectionPostProcess";
-import { Animation } from "../Animations/animation";
-import { VRCameraMetrics } from "../Cameras/VR/vrCameraMetrics";
 import { Logger } from "../Misc/logger";
 
+import { Animation } from "../Animations/animation";
+
+declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
+declare type RenderTargetTexture = import("../Materials/Textures/renderTargetTexture").RenderTargetTexture;
 declare type FreeCamera = import("./freeCamera").FreeCamera;
 declare type TargetCamera = import("./targetCamera").TargetCamera;
 
@@ -563,7 +559,7 @@ export class Camera extends Node {
 
             // for VR rig, there does not have to be a post process
             if (rigPostProcess) {
-                var isPass = rigPostProcess instanceof PassPostProcess;
+                var isPass = rigPostProcess.getEffectName() === "pass";
                 if (isPass) {
                     // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses
                     cam.isIntermediate = this._postProcesses.length === 0;
@@ -629,7 +625,7 @@ export class Camera extends Node {
     }
 
     /** @hidden */
-    protected _getViewMatrix(): Matrix {
+    public _getViewMatrix(): Matrix {
         return Matrix.Identity();
     }
 
@@ -968,84 +964,47 @@ export class Camera extends Node {
 
         switch (this.cameraRigMode) {
             case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
-                this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
-                this._rigCameras[1]._rigPostProcess = new AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras);
+                Camera._setStereoscopicAnaglyphRigMode(this);
                 break;
-
             case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
             case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
             case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
-                var isStereoscopicHoriz = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
-
-                this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
-                this._rigCameras[1]._rigPostProcess = new StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras, isStereoscopicHoriz);
+                Camera._setStereoscopicRigMode(this);
                 break;
-
             case Camera.RIG_MODE_VR:
-                var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
-
-                this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
-                this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
-                this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
-                this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
-                this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
-                this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
-
-                this._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
-                this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
-                this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
-                this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
-                this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
-                this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
-
-                if (metrics.compensateDistortion) {
-                    this._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics);
-                    this._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics);
-                }
+                Camera._setVRRigMode(this, rigParams);
                 break;
             case Camera.RIG_MODE_WEBVR:
-                if (rigParams.vrDisplay) {
-                    var leftEye = rigParams.vrDisplay.getEyeParameters('left');
-                    var rightEye = rigParams.vrDisplay.getEyeParameters('right');
-
-                    //Left eye
-                    this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
-                    this._rigCameras[0].setCameraRigParameter("left", true);
-                    //leaving this for future reference
-                    this._rigCameras[0].setCameraRigParameter("specs", rigParams.specs);
-                    this._rigCameras[0].setCameraRigParameter("eyeParameters", leftEye);
-                    this._rigCameras[0].setCameraRigParameter("frameData", rigParams.frameData);
-                    this._rigCameras[0].setCameraRigParameter("parentCamera", rigParams.parentCamera);
-                    this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
-                    this._rigCameras[0].getProjectionMatrix = this._getWebVRProjectionMatrix;
-                    this._rigCameras[0].parent = this;
-                    this._rigCameras[0]._getViewMatrix = this._getWebVRViewMatrix;
-
-                    //Right eye
-                    this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
-                    this._rigCameras[1].setCameraRigParameter('eyeParameters', rightEye);
-                    this._rigCameras[1].setCameraRigParameter("specs", rigParams.specs);
-                    this._rigCameras[1].setCameraRigParameter("frameData", rigParams.frameData);
-                    this._rigCameras[1].setCameraRigParameter("parentCamera", rigParams.parentCamera);
-                    this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
-                    this._rigCameras[1].getProjectionMatrix = this._getWebVRProjectionMatrix;
-                    this._rigCameras[1].parent = this;
-                    this._rigCameras[1]._getViewMatrix = this._getWebVRViewMatrix;
-
-                    if (Camera.UseAlternateWebVRRendering) {
-                        this._rigCameras[1]._skipRendering = true;
-                        this._rigCameras[0]._alternateCamera = this._rigCameras[1];
-                    }
-                }
+                Camera._setWebVRRigMode(this, rigParams);
                 break;
-
         }
 
         this._cascadePostProcessesToRigCams();
         this.update();
     }
 
-    private _getVRProjectionMatrix(): Matrix {
+    /** @hidden */
+    public static _setStereoscopicRigMode(camera: Camera) {
+        throw "Import Cameras/RigModes/stereoscopicRigMode before using stereoscopic rig mode";
+    }
+
+    /** @hidden */
+    public static _setStereoscopicAnaglyphRigMode(camera: Camera) {
+        throw "Import Cameras/RigModes/stereoscopicAnaglyphRigMode before using stereoscopic anaglyph rig mode";
+    }
+
+    /** @hidden */
+    public static _setVRRigMode(camera: Camera, rigParams: any) {
+        throw "Import Cameras/RigModes/vrRigMode before using VR rig mode";
+    }
+
+    /** @hidden */
+    public static _setWebVRRigMode(camera: Camera, rigParams: any) {
+        throw "Import Cameras/RigModes/WebVRRigMode before using Web VR rig mode";
+    }
+
+    /** @hidden */
+    public _getVRProjectionMatrix(): Matrix {
         Matrix.PerspectiveFovLHToRef(this._cameraRigParams.vrMetrics.aspectRatioFov, this._cameraRigParams.vrMetrics.aspectRatio, this.minZ, this.maxZ, this._cameraRigParams.vrWorkMatrix);
         this._cameraRigParams.vrWorkMatrix.multiplyToRef(this._cameraRigParams.vrHMatrix, this._projectionMatrix);
         return this._projectionMatrix;
@@ -1062,16 +1021,18 @@ export class Camera extends Node {
     /**
      * This function MUST be overwritten by the different WebVR cameras available.
      * The context in which it is running is the RIG camera. So 'this' is the TargetCamera, left or right.
+     * @hidden
      */
-    protected _getWebVRProjectionMatrix(): Matrix {
+    public _getWebVRProjectionMatrix(): Matrix {
         return Matrix.Identity();
     }
 
     /**
      * This function MUST be overwritten by the different WebVR cameras available.
      * The context in which it is running is the RIG camera. So 'this' is the TargetCamera, left or right.
+     * @hidden
      */
-    protected _getWebVRViewMatrix(): Matrix {
+    public _getWebVRViewMatrix(): Matrix {
         return Matrix.Identity();
     }
 

+ 2 - 0
src/Cameras/deviceOrientationCamera.ts

@@ -3,6 +3,8 @@ import { Scene } from "../scene";
 import { Quaternion, Vector3, Axis } from "../Maths/math";
 import { Node } from "../node";
 
+import "./Inputs/freeCameraDeviceOrientationInput";
+
 Node.AddNodeConstructor("DeviceOrientationCamera", (name, scene) => {
     return () => new DeviceOrientationCamera(name, Vector3.Zero(), scene);
 });

+ 0 - 20
src/Cameras/freeCameraInputsManager.ts

@@ -2,9 +2,7 @@ import { FreeCamera } from "./freeCamera";
 import { CameraInputsManager } from "./cameraInputsManager";
 import { FreeCameraKeyboardMoveInput } from "../Cameras/Inputs/freeCameraKeyboardMoveInput";
 import { FreeCameraMouseInput } from "../Cameras/Inputs/freeCameraMouseInput";
-import { FreeCameraDeviceOrientationInput } from "../Cameras/Inputs/freeCameraDeviceOrientationInput";
 import { FreeCameraTouchInput } from "../Cameras/Inputs/freeCameraTouchInput";
-import { FreeCameraVirtualJoystickInput } from "../Cameras/Inputs/freeCameraVirtualJoystickInput";
 
 /**
  * Default Inputs manager for the FreeCamera.
@@ -40,15 +38,6 @@ export class FreeCameraInputsManager extends CameraInputsManager<FreeCamera> {
     }
 
     /**
-     * Add orientation input support to the input manager.
-     * @returns the current input manager
-     */
-    addDeviceOrientation(): FreeCameraInputsManager {
-        this.add(new FreeCameraDeviceOrientationInput());
-        return this;
-    }
-
-    /**
      * Add touch input support to the input manager.
      * @returns the current input manager
      */
@@ -56,13 +45,4 @@ export class FreeCameraInputsManager extends CameraInputsManager<FreeCamera> {
         this.add(new FreeCameraTouchInput());
         return this;
     }
-
-    /**
-     * Add virtual joystick input support to the input manager.
-     * @returns the current input manager
-     */
-    addVirtualJoystick(): FreeCameraInputsManager {
-        this.add(new FreeCameraVirtualJoystickInput());
-        return this;
-    }
 }

+ 2 - 1
src/Cameras/index.ts

@@ -16,4 +16,5 @@ export * from "./Stereoscopic/index";
 export * from "./universalCamera";
 export * from "./virtualJoysticksCamera";
 export * from "./VR/index";
-export * from "./XR/index";
+export * from "./XR/index";
+export * from "./RigModes/index";

+ 3 - 0
src/Cameras/virtualJoysticksCamera.ts

@@ -2,6 +2,9 @@ import { FreeCamera } from "./freeCamera";
 import { Scene } from "../scene";
 import { Vector3 } from "../Maths/math";
 import { Node } from "../node";
+
+import "./Inputs/freeCameraVirtualJoystickInput";
+
 Node.AddNodeConstructor("VirtualJoysticksCamera", (name, scene) => {
     return () => new VirtualJoysticksCamera(name, Vector3.Zero(), scene);
 });

+ 89 - 4
src/Lights/Shadows/shadowGenerator.ts

@@ -26,6 +26,37 @@ import { Constants } from "../../Engines/constants";
 import "../../Shaders/shadowMap.fragment";
 import "../../Shaders/shadowMap.vertex";
 import "../../Shaders/depthBoxBlur.fragment";
+import { Observable } from '../../Misc/observable';
+
+/**
+ * Defines the options associated with the creation of a custom shader for a shadow generator.
+ */
+export interface ICustomShaderOptions {
+    /**
+     * Gets or sets the custom shader name to use
+     */
+    shaderName: string;
+
+    /**
+     * The list of attribute names used in the shader
+     */
+    attributes?: string[];
+
+    /**
+     * The list of unifrom names used in the shader
+     */
+    uniforms?: string[];
+
+    /**
+     * The list of sampler names used in the shader
+     */
+    samplers?: string[];
+
+    /**
+     * The list of defines used in the shader
+     */
+    defines?: string[];
+}
 
 /**
  * Interface to implement to create a shadow generator compatible with BJS.
@@ -181,6 +212,14 @@ export class ShadowGenerator implements IShadowGenerator {
      */
     public static readonly QUALITY_LOW = 2;
 
+    /** Gets or sets the custom shader name to use */
+    public customShaderOptions: ICustomShaderOptions;
+
+    /**
+     * Observable triggered before the shadow is rendered. Can be used to update internal effect state
+     */
+    public onBeforeShadowMapRenderObservable = new Observable<Effect>();
+
     private _bias = 0.00005;
     /**
      * Gets the bias: offset applied on the depth preventing acnea (in light direction).
@@ -926,6 +965,9 @@ export class ShadowGenerator implements IShadowGenerator {
                 engine.setState(true, 0, false, true);
             }
 
+            // Observable
+            this.onBeforeShadowMapRenderObservable.notifyObservers(this._effect);
+
             // Draw
             mesh._processRendering(subMesh, this._effect, Material.TriangleFillMode, batch, hardwareInstancedRendering,
                 (isInstance, world) => this._effect.setMatrix("world", world));
@@ -1123,14 +1165,57 @@ export class ShadowGenerator implements IShadowGenerator {
             attribs.push("world3");
         }
 
+        if (this.customShaderOptions) {
+            if (this.customShaderOptions.defines) {
+                for (var define of this.customShaderOptions.defines) {
+                    if (defines.indexOf(define) === -1) {
+                        defines.push(define);
+                    }
+                }
+            }
+        }
+
         // Get correct effect
         var join = defines.join("\n");
         if (this._cachedDefines !== join) {
             this._cachedDefines = join;
-            this._effect = this._scene.getEngine().createEffect("shadowMap",
-                attribs,
-                ["world", "mBones", "viewProjection", "diffuseMatrix", "lightData", "depthValues", "biasAndScale", "morphTargetInfluences", "boneTextureWidth"],
-                ["diffuseSampler", "boneSampler"], join,
+
+            let shaderName = "shadowMap";
+            let uniforms = ["world", "mBones", "viewProjection", "diffuseMatrix", "lightData", "depthValues", "biasAndScale", "morphTargetInfluences", "boneTextureWidth"];
+            let samplers = ["diffuseSampler", "boneSampler"];
+
+            // Custom shader?
+            if (this.customShaderOptions) {
+                shaderName = this.customShaderOptions.shaderName;
+
+                if (this.customShaderOptions.attributes) {
+                    for (var attrib of this.customShaderOptions.attributes) {
+                        if (attribs.indexOf(attrib) === -1) {
+                            attribs.push(attrib);
+                        }
+                    }
+                }
+
+                if (this.customShaderOptions.uniforms) {
+                    for (var uniform of this.customShaderOptions.uniforms) {
+                        if (uniforms.indexOf(uniform) === -1) {
+                            uniforms.push(uniform);
+                        }
+                    }
+                }
+
+                if (this.customShaderOptions.samplers) {
+                    for (var sampler of this.customShaderOptions.samplers) {
+                        if (samplers.indexOf(sampler) === -1) {
+                            samplers.push(sampler);
+                        }
+                    }
+                }
+            }
+
+            this._effect = this._scene.getEngine().createEffect(shaderName,
+                attribs, uniforms,
+                samplers, join,
                 undefined, undefined, undefined, { maxSimultaneousMorphTargets: morphInfluencers });
         }
 

+ 8 - 0
src/PostProcesses/postProcess.ts

@@ -144,6 +144,14 @@ export class PostProcess {
     private _texelSize = Vector2.Zero();
     private _forcedOutputTexture: InternalTexture;
 
+    /**
+     * Returns the fragment url or shader name used in the post process.
+     * @returns the fragment url or name in the shader store.
+     */
+    public getEffectName(): string {
+        return this._fragmentUrl;
+    }
+
     // Events
 
     /**

+ 2 - 1
src/Sprites/spriteManager.ts

@@ -303,7 +303,8 @@ export class SpriteManager implements ISpriteManager {
      */
     public render(): void {
         // Check
-        if (!this._effectBase.isReady() || !this._effectFog.isReady() || !this._spriteTexture || !this._spriteTexture.isReady()) {
+        if (!this._effectBase.isReady() || !this._effectFog.isReady() || !this._spriteTexture
+            || !this._spriteTexture.isReady() || !this.sprites.length) {
             return;
         }