Browse Source

Merge pull request #5523 from BabylonJS/master

merge
David Catuhe 6 years ago
parent
commit
52d0cc0b1a
52 changed files with 15595 additions and 14933 deletions
  1. 7362 7334
      Playground/babylon.d.txt
  2. 7362 7334
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 59 23
      dist/preview release/babylon.max.js
  5. 59 23
      dist/preview release/babylon.no-module.max.js
  6. 1 1
      dist/preview release/babylon.worker.js
  7. 59 23
      dist/preview release/es6.js
  8. 1 1
      dist/preview release/gui/babylon.gui.js
  9. 1 1
      dist/preview release/gui/babylon.gui.min.js
  10. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  11. 7 7
      dist/preview release/inspector/babylon.inspector.bundle.js
  12. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  13. 1 1
      dist/preview release/viewer/babylon.viewer.js
  14. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  15. 3 0
      dist/preview release/what's new.md
  16. 1 1
      gui/src/2D/controls/checkbox.ts
  17. 13 4
      inspector/src/components/actionTabs/lines/floatLineComponent.tsx
  18. 18 7
      inspector/src/components/actionTabs/lines/textInputLineComponent.tsx
  19. 4 0
      inspector/src/components/actionTabs/lines/textureLineComponent.tsx
  20. 12 12
      inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx
  21. 14 14
      inspector/src/components/actionTabs/tabs/debugTabComponent.tsx
  22. 65 1
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  23. 4 4
      inspector/src/components/actionTabs/tabs/propertyGrids/gridPropertyGridComponent.tsx
  24. 35 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/checkboxPropertyGridComponent.tsx
  25. 25 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx
  26. 33 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/ellipsePropertyGridComponent.tsx
  27. 42 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/imageBasedSliderPropertyGridComponent.tsx
  28. 52 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx
  29. 55 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/linePropertyGridComponent.tsx
  30. 38 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/radioButtonPropertyGridComponent.tsx
  31. 34 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/rectanglePropertyGridComponent.tsx
  32. 44 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/sliderPropertyGridComponent.tsx
  33. 15 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx
  34. 13 13
      inspector/src/components/actionTabs/tabs/propertyGrids/meshes/axesViewerComponent.tsx
  35. 14 14
      inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx
  36. 24 24
      inspector/src/components/sceneExplorer/entities/meshTreeItemComponent.tsx
  37. 10 10
      inspector/src/components/sceneExplorer/entities/sceneTreeItemComponent.tsx
  38. 7 7
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  39. 2 2
      inspector/src/components/sceneExplorer/treeItemComponent.tsx
  40. 4 4
      inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx
  41. 3 3
      inspector/src/tools.ts
  42. 6 4
      sandbox/index.js
  43. 1 0
      src/Cameras/babylon.camera.ts
  44. 17 9
      src/Cameras/babylon.targetCamera.ts
  45. 30 25
      src/Materials/Textures/babylon.baseTexture.ts
  46. 5 0
      src/Materials/babylon.material.ts
  47. 1 4
      src/Mesh/babylon.meshBuilder.ts
  48. 24 11
      src/Mesh/babylon.transformNode.ts
  49. 5 0
      src/babylon.node.ts
  50. 6 0
      src/babylon.scene.ts
  51. 0 5
      tests/validation/config.json
  52. 0 1
      what's new.md

File diff suppressed because it is too large
+ 7362 - 7334
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 7362 - 7334
dist/preview release/babylon.d.ts


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


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

@@ -18827,6 +18827,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Gets or sets a boolean used to define if the node must be serialized
              * Gets or sets a boolean used to define if the node must be serialized
              */
              */
             this.doNotSerialize = false;
             this.doNotSerialize = false;
@@ -20514,17 +20518,7 @@ var BABYLON;
             var dv = TransformNode._lookAtVectorCache;
             var dv = TransformNode._lookAtVectorCache;
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             targetPoint.subtractToRef(pos, dv);
             targetPoint.subtractToRef(pos, dv);
-            var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
-            var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
-            var pitch = Math.atan2(dv.y, len);
-            if (this.rotationQuaternion) {
-                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
-            }
-            else {
-                this.rotation.x = pitch + pitchCor;
-                this.rotation.y = yaw + yawCor;
-                this.rotation.z = rollCor;
-            }
+            this.setDirection(dv, yawCor, pitchCor, rollCor);
             // Correct for parent's rotation offset
             // Correct for parent's rotation offset
             if (space === BABYLON.Space.WORLD && this.parent) {
             if (space === BABYLON.Space.WORLD && this.parent) {
                 if (this.rotationQuaternion) {
                 if (this.rotationQuaternion) {
@@ -20579,6 +20573,31 @@ var BABYLON;
             return this;
             return this;
         };
         };
         /**
         /**
+         * Sets this transform node rotation to the given local axis.
+         * @param localAxis the axis in local space
+         * @param yawCor optional yaw (y-axis) correction in radians
+         * @param pitchCor optional pitch (x-axis) correction in radians
+         * @param rollCor optional roll (z-axis) correction in radians
+         * @returns this TransformNode
+         */
+        TransformNode.prototype.setDirection = function (localAxis, yawCor, pitchCor, rollCor) {
+            if (yawCor === void 0) { yawCor = 0; }
+            if (pitchCor === void 0) { pitchCor = 0; }
+            if (rollCor === void 0) { rollCor = 0; }
+            var yaw = -Math.atan2(localAxis.z, localAxis.x) - Math.PI / 2;
+            var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+            var pitch = Math.atan2(localAxis.y, len);
+            if (this.rotationQuaternion) {
+                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
+            }
+            else {
+                this.rotation.x = pitch + pitchCor;
+                this.rotation.y = yaw + yawCor;
+                this.rotation.z = rollCor;
+            }
+            return this;
+        };
+        /**
          * Sets a new pivot point to the current node
          * Sets a new pivot point to the current node
          * @param point defines the new pivot point to use
          * @param point defines the new pivot point to use
          * @param space defines if the point is in world or local space (local by default)
          * @param space defines if the point is in world or local space (local by default)
@@ -24614,6 +24633,7 @@ var BABYLON;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].fov = this.fov;
                 this._rigCameras[i].fov = this.fov;
+                this._rigCameras[i].upVector.copyFrom(this.upVector);
             }
             }
             // only update viewport when ANAGLYPH
             // only update viewport when ANAGLYPH
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
@@ -25844,6 +25864,10 @@ var BABYLON;
              */
              */
             _this.metadata = null;
             _this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            _this.reservedDataStore = null;
+            /**
              * Use this array to add regular expressions used to disable offline support for specific urls
              * Use this array to add regular expressions used to disable offline support for specific urls
              */
              */
             _this.disableOfflineSupportExceptionRules = new Array();
             _this.disableOfflineSupportExceptionRules = new Array();
@@ -31658,6 +31682,10 @@ var BABYLON;
              * Gets or sets an object used to store user defined information.
              * Gets or sets an object used to store user defined information.
              */
              */
             this.metadata = null;
             this.metadata = null;
+            /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
             this._hasAlpha = false;
             this._hasAlpha = false;
             /**
             /**
              * Defines if the alpha value should be determined via the rgb values.
              * Defines if the alpha value should be determined via the rgb values.
@@ -31746,8 +31774,8 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
             if (this._scene) {
-                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
                 this.uniqueId = this._scene.getUniqueId();
+                this._scene.addTexture(this);
             }
             }
             this._uid = null;
             this._uid = null;
         }
         }
@@ -36959,6 +36987,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Specifies if the ready state should be checked on each call
              * Specifies if the ready state should be checked on each call
              */
              */
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnEveryCall = false;
@@ -49055,6 +49087,8 @@ var BABYLON;
             /** @hidden */
             /** @hidden */
             _this._currentTarget = BABYLON.Vector3.Zero();
             _this._currentTarget = BABYLON.Vector3.Zero();
             /** @hidden */
             /** @hidden */
+            _this._initialFocalDistance = 1;
+            /** @hidden */
             _this._viewMatrix = BABYLON.Matrix.Zero();
             _this._viewMatrix = BABYLON.Matrix.Zero();
             /** @hidden */
             /** @hidden */
             _this._camMatrix = BABYLON.Matrix.Zero();
             _this._camMatrix = BABYLON.Matrix.Zero();
@@ -49174,6 +49208,7 @@ var BABYLON;
         /** @hidden */
         /** @hidden */
         TargetCamera.prototype.setTarget = function (target) {
         TargetCamera.prototype.setTarget = function (target) {
             this.upVector.normalize();
             this.upVector.normalize();
+            this._initialFocalDistance = target.subtract(this.position).length();
             if (this.position.z === target.z) {
             if (this.position.z === target.z) {
                 this.position.z += BABYLON.Epsilon;
                 this.position.z += BABYLON.Epsilon;
             }
             }
@@ -49374,10 +49409,8 @@ var BABYLON;
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft.position);
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
-                    camLeft.setTarget(this.getTarget());
-                    camRight.setTarget(this.getTarget());
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);
                     break;
                     break;
                 case BABYLON.Camera.RIG_MODE_VR:
                 case BABYLON.Camera.RIG_MODE_VR:
                     if (camLeft.rotationQuaternion) {
                     if (camLeft.rotationQuaternion) {
@@ -49394,13 +49427,17 @@ var BABYLON;
             }
             }
             _super.prototype._updateRigCameras.call(this);
             _super.prototype._updateRigCameras.call(this);
         };
         };
-        TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
+        TargetCamera.prototype._getRigCamPositionAndTarget = function (halfSpace, rigCamera) {
             var target = this.getTarget();
             var target = this.getTarget();
-            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);
+            TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);
+            var newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);
+            BABYLON.Matrix.TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
-            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);
+            rigCamera.setTarget(newFocalTarget);
         };
         };
         /**
         /**
          * Gets the current object class name.
          * Gets the current object class name.
@@ -49411,6 +49448,7 @@ var BABYLON;
         };
         };
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetFocalPoint = new BABYLON.Vector3();
         __decorate([
         __decorate([
             BABYLON.serializeAsVector3()
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
         ], TargetCamera.prototype, "rotation", void 0);
@@ -70660,9 +70698,7 @@ var BABYLON;
             vertexData.applyToMesh(plane, options.updatable);
             vertexData.applyToMesh(plane, options.updatable);
             if (options.sourcePlane) {
             if (options.sourcePlane) {
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
-                var dot = BABYLON.Vector3.Dot(plane.position, options.sourcePlane.normal);
-                var flip = dot >= 0;
-                plane.lookAt(BABYLON.Vector3.Zero(), 0, flip ? Math.PI : 0, 0);
+                plane.setDirection(options.sourcePlane.normal);
             }
             }
             return plane;
             return plane;
         };
         };

+ 59 - 23
dist/preview release/babylon.no-module.max.js

@@ -18794,6 +18794,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Gets or sets a boolean used to define if the node must be serialized
              * Gets or sets a boolean used to define if the node must be serialized
              */
              */
             this.doNotSerialize = false;
             this.doNotSerialize = false;
@@ -20481,17 +20485,7 @@ var BABYLON;
             var dv = TransformNode._lookAtVectorCache;
             var dv = TransformNode._lookAtVectorCache;
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             targetPoint.subtractToRef(pos, dv);
             targetPoint.subtractToRef(pos, dv);
-            var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
-            var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
-            var pitch = Math.atan2(dv.y, len);
-            if (this.rotationQuaternion) {
-                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
-            }
-            else {
-                this.rotation.x = pitch + pitchCor;
-                this.rotation.y = yaw + yawCor;
-                this.rotation.z = rollCor;
-            }
+            this.setDirection(dv, yawCor, pitchCor, rollCor);
             // Correct for parent's rotation offset
             // Correct for parent's rotation offset
             if (space === BABYLON.Space.WORLD && this.parent) {
             if (space === BABYLON.Space.WORLD && this.parent) {
                 if (this.rotationQuaternion) {
                 if (this.rotationQuaternion) {
@@ -20546,6 +20540,31 @@ var BABYLON;
             return this;
             return this;
         };
         };
         /**
         /**
+         * Sets this transform node rotation to the given local axis.
+         * @param localAxis the axis in local space
+         * @param yawCor optional yaw (y-axis) correction in radians
+         * @param pitchCor optional pitch (x-axis) correction in radians
+         * @param rollCor optional roll (z-axis) correction in radians
+         * @returns this TransformNode
+         */
+        TransformNode.prototype.setDirection = function (localAxis, yawCor, pitchCor, rollCor) {
+            if (yawCor === void 0) { yawCor = 0; }
+            if (pitchCor === void 0) { pitchCor = 0; }
+            if (rollCor === void 0) { rollCor = 0; }
+            var yaw = -Math.atan2(localAxis.z, localAxis.x) - Math.PI / 2;
+            var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+            var pitch = Math.atan2(localAxis.y, len);
+            if (this.rotationQuaternion) {
+                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
+            }
+            else {
+                this.rotation.x = pitch + pitchCor;
+                this.rotation.y = yaw + yawCor;
+                this.rotation.z = rollCor;
+            }
+            return this;
+        };
+        /**
          * Sets a new pivot point to the current node
          * Sets a new pivot point to the current node
          * @param point defines the new pivot point to use
          * @param point defines the new pivot point to use
          * @param space defines if the point is in world or local space (local by default)
          * @param space defines if the point is in world or local space (local by default)
@@ -24581,6 +24600,7 @@ var BABYLON;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].fov = this.fov;
                 this._rigCameras[i].fov = this.fov;
+                this._rigCameras[i].upVector.copyFrom(this.upVector);
             }
             }
             // only update viewport when ANAGLYPH
             // only update viewport when ANAGLYPH
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
@@ -25811,6 +25831,10 @@ var BABYLON;
              */
              */
             _this.metadata = null;
             _this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            _this.reservedDataStore = null;
+            /**
              * Use this array to add regular expressions used to disable offline support for specific urls
              * Use this array to add regular expressions used to disable offline support for specific urls
              */
              */
             _this.disableOfflineSupportExceptionRules = new Array();
             _this.disableOfflineSupportExceptionRules = new Array();
@@ -31625,6 +31649,10 @@ var BABYLON;
              * Gets or sets an object used to store user defined information.
              * Gets or sets an object used to store user defined information.
              */
              */
             this.metadata = null;
             this.metadata = null;
+            /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
             this._hasAlpha = false;
             this._hasAlpha = false;
             /**
             /**
              * Defines if the alpha value should be determined via the rgb values.
              * Defines if the alpha value should be determined via the rgb values.
@@ -31713,8 +31741,8 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
             if (this._scene) {
-                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
                 this.uniqueId = this._scene.getUniqueId();
+                this._scene.addTexture(this);
             }
             }
             this._uid = null;
             this._uid = null;
         }
         }
@@ -36926,6 +36954,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Specifies if the ready state should be checked on each call
              * Specifies if the ready state should be checked on each call
              */
              */
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnEveryCall = false;
@@ -49022,6 +49054,8 @@ var BABYLON;
             /** @hidden */
             /** @hidden */
             _this._currentTarget = BABYLON.Vector3.Zero();
             _this._currentTarget = BABYLON.Vector3.Zero();
             /** @hidden */
             /** @hidden */
+            _this._initialFocalDistance = 1;
+            /** @hidden */
             _this._viewMatrix = BABYLON.Matrix.Zero();
             _this._viewMatrix = BABYLON.Matrix.Zero();
             /** @hidden */
             /** @hidden */
             _this._camMatrix = BABYLON.Matrix.Zero();
             _this._camMatrix = BABYLON.Matrix.Zero();
@@ -49141,6 +49175,7 @@ var BABYLON;
         /** @hidden */
         /** @hidden */
         TargetCamera.prototype.setTarget = function (target) {
         TargetCamera.prototype.setTarget = function (target) {
             this.upVector.normalize();
             this.upVector.normalize();
+            this._initialFocalDistance = target.subtract(this.position).length();
             if (this.position.z === target.z) {
             if (this.position.z === target.z) {
                 this.position.z += BABYLON.Epsilon;
                 this.position.z += BABYLON.Epsilon;
             }
             }
@@ -49341,10 +49376,8 @@ var BABYLON;
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft.position);
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
-                    camLeft.setTarget(this.getTarget());
-                    camRight.setTarget(this.getTarget());
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);
                     break;
                     break;
                 case BABYLON.Camera.RIG_MODE_VR:
                 case BABYLON.Camera.RIG_MODE_VR:
                     if (camLeft.rotationQuaternion) {
                     if (camLeft.rotationQuaternion) {
@@ -49361,13 +49394,17 @@ var BABYLON;
             }
             }
             _super.prototype._updateRigCameras.call(this);
             _super.prototype._updateRigCameras.call(this);
         };
         };
-        TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
+        TargetCamera.prototype._getRigCamPositionAndTarget = function (halfSpace, rigCamera) {
             var target = this.getTarget();
             var target = this.getTarget();
-            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);
+            TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);
+            var newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);
+            BABYLON.Matrix.TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
-            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);
+            rigCamera.setTarget(newFocalTarget);
         };
         };
         /**
         /**
          * Gets the current object class name.
          * Gets the current object class name.
@@ -49378,6 +49415,7 @@ var BABYLON;
         };
         };
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetFocalPoint = new BABYLON.Vector3();
         __decorate([
         __decorate([
             BABYLON.serializeAsVector3()
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
         ], TargetCamera.prototype, "rotation", void 0);
@@ -70627,9 +70665,7 @@ var BABYLON;
             vertexData.applyToMesh(plane, options.updatable);
             vertexData.applyToMesh(plane, options.updatable);
             if (options.sourcePlane) {
             if (options.sourcePlane) {
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
-                var dot = BABYLON.Vector3.Dot(plane.position, options.sourcePlane.normal);
-                var flip = dot >= 0;
-                plane.lookAt(BABYLON.Vector3.Zero(), 0, flip ? Math.PI : 0, 0);
+                plane.setDirection(options.sourcePlane.normal);
             }
             }
             return plane;
             return plane;
         };
         };

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


+ 59 - 23
dist/preview release/es6.js

@@ -18794,6 +18794,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Gets or sets a boolean used to define if the node must be serialized
              * Gets or sets a boolean used to define if the node must be serialized
              */
              */
             this.doNotSerialize = false;
             this.doNotSerialize = false;
@@ -20481,17 +20485,7 @@ var BABYLON;
             var dv = TransformNode._lookAtVectorCache;
             var dv = TransformNode._lookAtVectorCache;
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
             targetPoint.subtractToRef(pos, dv);
             targetPoint.subtractToRef(pos, dv);
-            var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
-            var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
-            var pitch = Math.atan2(dv.y, len);
-            if (this.rotationQuaternion) {
-                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
-            }
-            else {
-                this.rotation.x = pitch + pitchCor;
-                this.rotation.y = yaw + yawCor;
-                this.rotation.z = rollCor;
-            }
+            this.setDirection(dv, yawCor, pitchCor, rollCor);
             // Correct for parent's rotation offset
             // Correct for parent's rotation offset
             if (space === BABYLON.Space.WORLD && this.parent) {
             if (space === BABYLON.Space.WORLD && this.parent) {
                 if (this.rotationQuaternion) {
                 if (this.rotationQuaternion) {
@@ -20546,6 +20540,31 @@ var BABYLON;
             return this;
             return this;
         };
         };
         /**
         /**
+         * Sets this transform node rotation to the given local axis.
+         * @param localAxis the axis in local space
+         * @param yawCor optional yaw (y-axis) correction in radians
+         * @param pitchCor optional pitch (x-axis) correction in radians
+         * @param rollCor optional roll (z-axis) correction in radians
+         * @returns this TransformNode
+         */
+        TransformNode.prototype.setDirection = function (localAxis, yawCor, pitchCor, rollCor) {
+            if (yawCor === void 0) { yawCor = 0; }
+            if (pitchCor === void 0) { pitchCor = 0; }
+            if (rollCor === void 0) { rollCor = 0; }
+            var yaw = -Math.atan2(localAxis.z, localAxis.x) - Math.PI / 2;
+            var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+            var pitch = Math.atan2(localAxis.y, len);
+            if (this.rotationQuaternion) {
+                BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
+            }
+            else {
+                this.rotation.x = pitch + pitchCor;
+                this.rotation.y = yaw + yawCor;
+                this.rotation.z = rollCor;
+            }
+            return this;
+        };
+        /**
          * Sets a new pivot point to the current node
          * Sets a new pivot point to the current node
          * @param point defines the new pivot point to use
          * @param point defines the new pivot point to use
          * @param space defines if the point is in world or local space (local by default)
          * @param space defines if the point is in world or local space (local by default)
@@ -24581,6 +24600,7 @@ var BABYLON;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].fov = this.fov;
                 this._rigCameras[i].fov = this.fov;
+                this._rigCameras[i].upVector.copyFrom(this.upVector);
             }
             }
             // only update viewport when ANAGLYPH
             // only update viewport when ANAGLYPH
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
             if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
@@ -25811,6 +25831,10 @@ var BABYLON;
              */
              */
             _this.metadata = null;
             _this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            _this.reservedDataStore = null;
+            /**
              * Use this array to add regular expressions used to disable offline support for specific urls
              * Use this array to add regular expressions used to disable offline support for specific urls
              */
              */
             _this.disableOfflineSupportExceptionRules = new Array();
             _this.disableOfflineSupportExceptionRules = new Array();
@@ -31625,6 +31649,10 @@ var BABYLON;
              * Gets or sets an object used to store user defined information.
              * Gets or sets an object used to store user defined information.
              */
              */
             this.metadata = null;
             this.metadata = null;
+            /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
             this._hasAlpha = false;
             this._hasAlpha = false;
             /**
             /**
              * Defines if the alpha value should be determined via the rgb values.
              * Defines if the alpha value should be determined via the rgb values.
@@ -31713,8 +31741,8 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
             if (this._scene) {
-                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
                 this.uniqueId = this._scene.getUniqueId();
+                this._scene.addTexture(this);
             }
             }
             this._uid = null;
             this._uid = null;
         }
         }
@@ -36926,6 +36954,10 @@ var BABYLON;
              */
              */
             this.metadata = null;
             this.metadata = null;
             /**
             /**
+             * For internal use only. Please do not use.
+             */
+            this.reservedDataStore = null;
+            /**
              * Specifies if the ready state should be checked on each call
              * Specifies if the ready state should be checked on each call
              */
              */
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnEveryCall = false;
@@ -49022,6 +49054,8 @@ var BABYLON;
             /** @hidden */
             /** @hidden */
             _this._currentTarget = BABYLON.Vector3.Zero();
             _this._currentTarget = BABYLON.Vector3.Zero();
             /** @hidden */
             /** @hidden */
+            _this._initialFocalDistance = 1;
+            /** @hidden */
             _this._viewMatrix = BABYLON.Matrix.Zero();
             _this._viewMatrix = BABYLON.Matrix.Zero();
             /** @hidden */
             /** @hidden */
             _this._camMatrix = BABYLON.Matrix.Zero();
             _this._camMatrix = BABYLON.Matrix.Zero();
@@ -49141,6 +49175,7 @@ var BABYLON;
         /** @hidden */
         /** @hidden */
         TargetCamera.prototype.setTarget = function (target) {
         TargetCamera.prototype.setTarget = function (target) {
             this.upVector.normalize();
             this.upVector.normalize();
+            this._initialFocalDistance = target.subtract(this.position).length();
             if (this.position.z === target.z) {
             if (this.position.z === target.z) {
                 this.position.z += BABYLON.Epsilon;
                 this.position.z += BABYLON.Epsilon;
             }
             }
@@ -49341,10 +49376,8 @@ var BABYLON;
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
                     var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft.position);
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
-                    camLeft.setTarget(this.getTarget());
-                    camRight.setTarget(this.getTarget());
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);
                     break;
                     break;
                 case BABYLON.Camera.RIG_MODE_VR:
                 case BABYLON.Camera.RIG_MODE_VR:
                     if (camLeft.rotationQuaternion) {
                     if (camLeft.rotationQuaternion) {
@@ -49361,13 +49394,17 @@ var BABYLON;
             }
             }
             _super.prototype._updateRigCameras.call(this);
             _super.prototype._updateRigCameras.call(this);
         };
         };
-        TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
+        TargetCamera.prototype._getRigCamPositionAndTarget = function (halfSpace, rigCamera) {
             var target = this.getTarget();
             var target = this.getTarget();
-            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);
+            TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);
+            var newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);
+            BABYLON.Matrix.TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
-            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);
+            rigCamera.setTarget(newFocalTarget);
         };
         };
         /**
         /**
          * Gets the current object class name.
          * Gets the current object class name.
@@ -49378,6 +49415,7 @@ var BABYLON;
         };
         };
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetFocalPoint = new BABYLON.Vector3();
         __decorate([
         __decorate([
             BABYLON.serializeAsVector3()
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
         ], TargetCamera.prototype, "rotation", void 0);
@@ -70627,9 +70665,7 @@ var BABYLON;
             vertexData.applyToMesh(plane, options.updatable);
             vertexData.applyToMesh(plane, options.updatable);
             if (options.sourcePlane) {
             if (options.sourcePlane) {
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
-                var dot = BABYLON.Vector3.Dot(plane.position, options.sourcePlane.normal);
-                var flip = dot >= 0;
-                plane.lookAt(BABYLON.Vector3.Zero(), 0, flip ? Math.PI : 0, 0);
+                plane.setDirection(options.sourcePlane.normal);
             }
             }
             return plane;
             return plane;
         };
         };

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


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


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


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


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


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


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


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

@@ -69,6 +69,7 @@
 - GizmoManager clearGizmoOnEmptyPointerEvent options and onAttachedToMeshObservable event ([TrevorDev](https://github.com/TrevorDev))
 - GizmoManager clearGizmoOnEmptyPointerEvent options and onAttachedToMeshObservable event ([TrevorDev](https://github.com/TrevorDev))
 - Added support for overriding the mesh used for the world matrix for a mesh with a skeleton ([bghgary](https://github.com/bghgary))
 - Added support for overriding the mesh used for the world matrix for a mesh with a skeleton ([bghgary](https://github.com/bghgary))
 - Added support for linking a bone to a transform node ([bghgary](https://github.com/bghgary))
 - Added support for linking a bone to a transform node ([bghgary](https://github.com/bghgary))
+- Factored out `setDirection` function from `lookAt` for transform node ([bghgary](https://github.com/bghgary))
 
 
 ### glTF Loader
 ### glTF Loader
 
 
@@ -87,6 +88,7 @@
 ### Materials Library
 ### Materials Library
 
 
 ## Bug fixes
 ## Bug fixes
+- Fixed anaglyph mode for Free and Universal cameras ([Deltakosh](https://github.com/deltakosh))
 - Fixed FileLoader's loading of a skybox, & added a parsed value for whether to create with PBR or STDMaterial ([Palmer-JC](https://github.com/Palmer-JC))
 - Fixed FileLoader's loading of a skybox, & added a parsed value for whether to create with PBR or STDMaterial ([Palmer-JC](https://github.com/Palmer-JC))
 - Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
@@ -112,6 +114,7 @@
 - Fixed effect layer compatibility with multi materials ([Sebavan](https://github.com/Sebavan))
 - Fixed effect layer compatibility with multi materials ([Sebavan](https://github.com/Sebavan))
 - Added a `DeepImmutable<T>` type to specifiy that a referenced object should be considered recursively immutable, meaning that all its properties are `readonly` and that if a property is a reference to an object, this object is also recursively immutable. ([barroij](https://github.com/barroij))
 - Added a `DeepImmutable<T>` type to specifiy that a referenced object should be considered recursively immutable, meaning that all its properties are `readonly` and that if a property is a reference to an object, this object is also recursively immutable. ([barroij](https://github.com/barroij))
 - Fixed `VideoTexture` poster property when autoplay is turned off.
 - Fixed `VideoTexture` poster property when autoplay is turned off.
+- Fixed position and rotation of plane mesh created by MeshBuilder.CreatePlane when specifying a source plane ([sable](https://github.com/thscott), [bghgary](https://github.com/bghgary))
 
 
 ### Viewer
 ### Viewer
 
 

+ 1 - 1
gui/src/2D/controls/checkbox.ts

@@ -88,7 +88,7 @@ export class Checkbox extends Control {
     }
     }
 
 
     protected _getTypeName(): string {
     protected _getTypeName(): string {
-        return "CheckBox";
+        return "Checkbox";
     }
     }
 
 
     /** @hidden */
     /** @hidden */

+ 13 - 4
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -9,6 +9,7 @@ interface IFloatLineComponentProps {
     propertyName: string,
     propertyName: string,
     lockObject?: LockObject,
     lockObject?: LockObject,
     onChange?: (newValue: number) => void,
     onChange?: (newValue: number) => void,
+    isInteger?: boolean,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
     additionalClass?: string
     additionalClass?: string
 }
 }
@@ -21,7 +22,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
         super(props);
         super(props);
 
 
         let currentValue = this.props.target[this.props.propertyName];
         let currentValue = this.props.target[this.props.propertyName];
-        this.state = { value: currentValue ? currentValue.toFixed(3) : "0" }
+        this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(3)) : "0" }
         this._store = currentValue;
         this._store = currentValue;
     }
     }
 
 
@@ -37,8 +38,10 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
         }
         }
 
 
         const newValue = nextProps.target[nextProps.propertyName];
         const newValue = nextProps.target[nextProps.propertyName];
-        if (newValue && newValue !== nextState.value) {
-            nextState.value = newValue.toFixed(3);
+        const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(3) : "0";
+
+        if (newValueString !== nextState.value) {
+            nextState.value = newValueString;
             return true;
             return true;
         }
         }
         return false;
         return false;
@@ -66,7 +69,13 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
             return;
             return;
         }
         }
 
 
-        let valueAsNumber = parseFloat(valueString);
+        let valueAsNumber: number
+
+        if (this.props.isInteger) {
+            valueAsNumber = parseInt(valueString);
+        } else {
+            valueAsNumber = parseFloat(valueString);
+        }
 
 
         this._localChange = true;
         this._localChange = true;
         this.setState({ value: valueString });
         this.setState({ value: valueString });

+ 18 - 7
inspector/src/components/actionTabs/lines/textInputLineComponent.tsx

@@ -5,9 +5,11 @@ import { LockObject } from "../tabs/propertyGrids/lockObject";
 
 
 interface ITextInputLineComponentProps {
 interface ITextInputLineComponentProps {
     label: string,
     label: string,
-    target: any,
     lockObject: LockObject,
     lockObject: LockObject,
-    propertyName: string,
+    target?: any,
+    propertyName?: string,
+    value?: string,
+    onChange?: (value: string) => void,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
 }
 }
 
 
@@ -17,7 +19,7 @@ export class TextInputLineComponent extends React.Component<ITextInputLineCompon
     constructor(props: ITextInputLineComponentProps) {
     constructor(props: ITextInputLineComponentProps) {
         super(props);
         super(props);
 
 
-        this.state = { value: this.props.target[this.props.propertyName] || "" }
+        this.state = { value: this.props.value || this.props.target[this.props.propertyName!] || "" }
     }
     }
 
 
     componentWillUnmount() {
     componentWillUnmount() {
@@ -30,7 +32,7 @@ export class TextInputLineComponent extends React.Component<ITextInputLineCompon
             return true;
             return true;
         }
         }
 
 
-        const newValue = nextProps.target[nextProps.propertyName];
+        const newValue = nextProps.value || nextProps.target[nextProps.propertyName!];
         if (newValue !== nextState.value) {
         if (newValue !== nextState.value) {
             nextState.value = newValue || "";
             nextState.value = newValue || "";
             return true;
             return true;
@@ -39,12 +41,18 @@ export class TextInputLineComponent extends React.Component<ITextInputLineCompon
     }
     }
 
 
     raiseOnPropertyChanged(newValue: string, previousValue: string) {
     raiseOnPropertyChanged(newValue: string, previousValue: string) {
+        if (this.props.onChange) {
+            this.props.onChange(newValue);
+            return;
+        }
+
         if (!this.props.onPropertyChangedObservable) {
         if (!this.props.onPropertyChangedObservable) {
             return;
             return;
         }
         }
+
         this.props.onPropertyChangedObservable.notifyObservers({
         this.props.onPropertyChangedObservable.notifyObservers({
             object: this.props.target,
             object: this.props.target,
-            property: this.props.propertyName,
+            property: this.props.propertyName!,
             value: newValue,
             value: newValue,
             initialValue: previousValue
             initialValue: previousValue
         });
         });
@@ -53,11 +61,14 @@ export class TextInputLineComponent extends React.Component<ITextInputLineCompon
     updateValue(value: string) {
     updateValue(value: string) {
 
 
         this._localChange = true;
         this._localChange = true;
-        const store = this.props.target[this.props.propertyName];
+        const store = this.props.value || this.props.target[this.props.propertyName!];
         this.setState({ value: value });
         this.setState({ value: value });
 
 
         this.raiseOnPropertyChanged(value, store);
         this.raiseOnPropertyChanged(value, store);
-        this.props.target[this.props.propertyName] = value;
+
+        if (this.props.propertyName) {
+            this.props.target[this.props.propertyName] = value;
+        }
     }
     }
 
 
     render() {
     render() {

+ 4 - 0
inspector/src/components/actionTabs/lines/textureLineComponent.tsx

@@ -20,6 +20,10 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
         }
         }
     }
     }
 
 
+    shouldComponentUpdate(nextProps: ITextureLineComponentProps): boolean {
+        return (nextProps.texture !== this.props.texture);
+    }
+
     componentDidMount() {
     componentDidMount() {
         this.updatePreview();
         this.updatePreview();
     }
     }

+ 12 - 12
inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx

@@ -21,7 +21,7 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
         const material = this.props.material;
         const material = this.props.material;
         const texture = this.props.texture;
         const texture = this.props.texture;
 
 
-        this.state = { isDebugSelected: material && material.metadata && material.metadata.debugTexture === texture };
+        this.state = { isDebugSelected: material && material.reservedDataStore && material.reservedDataStore.debugTexture === texture };
     }
     }
 
 
 
 
@@ -51,8 +51,8 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
         }
         }
         const scene = material.getScene();
         const scene = material.getScene();
 
 
-        if (material.metadata && material.metadata.debugTexture === texture) {
-            const debugMaterial = material.metadata.debugMaterial;
+        if (material.reservedDataStore && material.reservedDataStore.debugTexture === texture) {
+            const debugMaterial = material.reservedDataStore.debugMaterial;
 
 
             for (var mesh of scene.meshes) {
             for (var mesh of scene.meshes) {
                 if (mesh.material === debugMaterial) {
                 if (mesh.material === debugMaterial) {
@@ -60,8 +60,8 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
                 }
                 }
             }
             }
             debugMaterial.dispose();
             debugMaterial.dispose();
-            material.metadata.debugTexture = null;
-            material.metadata.debugMaterial = null;
+            material.reservedDataStore.debugTexture = null;
+            material.reservedDataStore.debugMaterial = null;
 
 
             this.setState({ isDebugSelected: false });
             this.setState({ isDebugSelected: false });
             return;
             return;
@@ -69,8 +69,8 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
 
 
         let checkMaterial = material;
         let checkMaterial = material;
         let needToDisposeCheckMaterial = false;
         let needToDisposeCheckMaterial = false;
-        if (material.metadata && material.metadata.debugTexture) {
-            checkMaterial = material.metadata.debugMaterial;
+        if (material.reservedDataStore && material.reservedDataStore.debugTexture) {
+            checkMaterial = material.reservedDataStore.debugMaterial;
             needToDisposeCheckMaterial = true;
             needToDisposeCheckMaterial = true;
         }
         }
 
 
@@ -79,7 +79,7 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
         debugMaterial.sideOrientation = material.sideOrientation;
         debugMaterial.sideOrientation = material.sideOrientation;
         debugMaterial.emissiveTexture = texture!;
         debugMaterial.emissiveTexture = texture!;
         debugMaterial.forceDepthWrite = true;
         debugMaterial.forceDepthWrite = true;
-        debugMaterial.metadata = { hidden: true };
+        debugMaterial.reservedDataStore = { hidden: true };
 
 
         for (var mesh of scene.meshes) {
         for (var mesh of scene.meshes) {
             if (mesh.material === checkMaterial) {
             if (mesh.material === checkMaterial) {
@@ -87,12 +87,12 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
             }
             }
         }
         }
 
 
-        if (!material.metadata) {
-            material.metadata = {};
+        if (!material.reservedDataStore) {
+            material.reservedDataStore = {};
         }
         }
 
 
-        material.metadata.debugTexture = texture;
-        material.metadata.debugMaterial = debugMaterial;
+        material.reservedDataStore.debugTexture = texture;
+        material.reservedDataStore.debugMaterial = debugMaterial;
 
 
         if (this.props.onDebugSelectionChangeObservable) {
         if (this.props.onDebugSelectionChangeObservable) {
             this.props.onDebugSelectionChangeObservable.notifyObservers(texture!);
             this.props.onDebugSelectionChangeObservable.notifyObservers(texture!);

+ 14 - 14
inspector/src/components/actionTabs/tabs/debugTabComponent.tsx

@@ -20,18 +20,18 @@ export class DebugTabComponent extends PaneComponent {
             return;
             return;
         }
         }
 
 
-        if (!scene.metadata) {
-            scene.metadata = {};
+        if (!scene.reservedDataStore) {
+            scene.reservedDataStore = {};
         }
         }
 
 
         for (var mesh of scene.meshes) {
         for (var mesh of scene.meshes) {
-            if (mesh.skeleton && mesh.metadata && mesh.metadata.skeletonViewer) {
-                this._skeletonViewers.push(mesh.metadata.skeletonViewer);
+            if (mesh.skeleton && mesh.reservedDataStore && mesh.reservedDataStore.skeletonViewer) {
+                this._skeletonViewers.push(mesh.reservedDataStore.skeletonViewer);
             }
             }
         }
         }
 
 
         this._skeletonViewersEnabled = (this._skeletonViewers.length > 0);
         this._skeletonViewersEnabled = (this._skeletonViewers.length > 0);
-        this._physicsViewersEnabled = scene.metadata.physicsViewer != null;
+        this._physicsViewersEnabled = scene.reservedDataStore.physicsViewer != null;
     }
     }
 
 
     componentWillUnmount() {
     componentWillUnmount() {
@@ -57,15 +57,15 @@ export class DebugTabComponent extends PaneComponent {
                     var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, scene, true, 0);
                     var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, scene, true, 0);
                     viewer.isEnabled = true;
                     viewer.isEnabled = true;
                     this._skeletonViewers.push(viewer);
                     this._skeletonViewers.push(viewer);
-                    if (!mesh.metadata) {
-                        mesh.metadata = {};
+                    if (!mesh.reservedDataStore) {
+                        mesh.reservedDataStore = {};
                     }
                     }
-                    mesh.metadata.skeletonViewer = viewer;
+                    mesh.reservedDataStore.skeletonViewer = viewer;
                 }
                 }
             }
             }
         } else {
         } else {
             for (var index = 0; index < this._skeletonViewers.length; index++) {
             for (var index = 0; index < this._skeletonViewers.length; index++) {
-                this._skeletonViewers[index].mesh.metadata.skeletonViewer = null;
+                this._skeletonViewers[index].mesh.reservedDataStore.skeletonViewer = null;
                 this._skeletonViewers[index].dispose();
                 this._skeletonViewers[index].dispose();
             }
             }
             this._skeletonViewers = [];
             this._skeletonViewers = [];
@@ -79,21 +79,21 @@ export class DebugTabComponent extends PaneComponent {
 
 
         if (this._physicsViewersEnabled) {
         if (this._physicsViewersEnabled) {
             const physicsViewer = new BABYLON.Debug.PhysicsViewer(scene);
             const physicsViewer = new BABYLON.Debug.PhysicsViewer(scene);
-            scene.metadata.physicsViewer = physicsViewer;
+            scene.reservedDataStore.physicsViewer = physicsViewer;
 
 
             for (var mesh of scene.meshes) {
             for (var mesh of scene.meshes) {
                 if (mesh.physicsImpostor) {
                 if (mesh.physicsImpostor) {
                     let debugMesh = physicsViewer.showImpostor(mesh.physicsImpostor);
                     let debugMesh = physicsViewer.showImpostor(mesh.physicsImpostor);
 
 
                     if (debugMesh) {
                     if (debugMesh) {
-                        debugMesh.metadata = { hidden: true };
-                        debugMesh.material!.metadata = { hidden: true };
+                        debugMesh.reservedDataStore = { hidden: true };
+                        debugMesh.material!.reservedDataStore = { hidden: true };
                     }
                     }
                 }
                 }
             }
             }
         } else {
         } else {
-            scene.metadata.physicsViewer.dispose();
-            scene.metadata.physicsViewer = null;
+            scene.reservedDataStore.physicsViewer.dispose();
+            scene.reservedDataStore.physicsViewer = null;
         }
         }
     }
     }
 
 

+ 65 - 1
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -19,10 +19,18 @@ import { TextBlockPropertyGridComponent } from "./propertyGrids/gui/textBlockPro
 import { TextBlock } from "babylonjs-gui/2D/controls/textBlock";
 import { TextBlock } from "babylonjs-gui/2D/controls/textBlock";
 import { InputText } from "babylonjs-gui/2D/controls/inputText";
 import { InputText } from "babylonjs-gui/2D/controls/inputText";
 import { InputTextPropertyGridComponent } from "./propertyGrids/gui/inputTextPropertyGridComponent";
 import { InputTextPropertyGridComponent } from "./propertyGrids/gui/inputTextPropertyGridComponent";
-import { ColorPicker } from "babylonjs-gui";
+import { ColorPicker, Image, Slider, ImageBasedSlider, Rectangle, Ellipse, Checkbox, RadioButton, Line } from "babylonjs-gui";
 import { ColorPickerPropertyGridComponent } from "./propertyGrids/gui/colorPickerPropertyGridComponent";
 import { ColorPickerPropertyGridComponent } from "./propertyGrids/gui/colorPickerPropertyGridComponent";
 import { AnimationGroupGridComponent } from "./propertyGrids/animationGroupPropertyGridComponent";
 import { AnimationGroupGridComponent } from "./propertyGrids/animationGroupPropertyGridComponent";
 import { LockObject } from "./propertyGrids/lockObject";
 import { LockObject } from "./propertyGrids/lockObject";
+import { ImagePropertyGridComponent } from "./propertyGrids/gui/imagePropertyGridComponent";
+import { SliderPropertyGridComponent } from "./propertyGrids/gui/sliderPropertyGridComponent";
+import { ImageBasedSliderPropertyGridComponent } from "./propertyGrids/gui/imageBasedSliderPropertyGridComponent";
+import { RectanglePropertyGridComponent } from "./propertyGrids/gui/rectanglePropertyGridComponent";
+import { EllipsePropertyGridComponent } from "./propertyGrids/gui/ellipsePropertyGridComponent";
+import { CheckboxPropertyGridComponent } from "./propertyGrids/gui/checkboxPropertyGridComponent";
+import { RadioButtonPropertyGridComponent } from "./propertyGrids/gui/radioButtonPropertyGridComponent";
+import { LinePropertyGridComponent } from "./propertyGrids/gui/linePropertyGridComponent";
 
 
 export class PropertyGridTabComponent extends PaneComponent {
 export class PropertyGridTabComponent extends PaneComponent {
     private _timerIntervalId: number;
     private _timerIntervalId: number;
@@ -178,6 +186,62 @@ export class PropertyGridTabComponent extends PaneComponent {
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
             }
 
 
+            if (className === "Image") {
+                const image = entity as Image;
+                return (<ImagePropertyGridComponent image={image}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "Slider") {
+                const slider = entity as Slider;
+                return (<SliderPropertyGridComponent slider={slider}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "ImageBasedSlider") {
+                const imageBasedSlider = entity as ImageBasedSlider;
+                return (<ImageBasedSliderPropertyGridComponent imageBasedSlider={imageBasedSlider}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "Rectangle") {
+                const rectangle = entity as Rectangle;
+                return (<RectanglePropertyGridComponent rectangle={rectangle}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "Ellipse") {
+                const ellipse = entity as Ellipse;
+                return (<EllipsePropertyGridComponent ellipse={ellipse}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "Checkbox") {
+                const checkbox = entity as Checkbox;
+                return (<CheckboxPropertyGridComponent checkbox={checkbox}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "RadioButton") {
+                const radioButton = entity as RadioButton;
+                return (<RadioButtonPropertyGridComponent radioButton={radioButton}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "Line") {
+                const line = entity as Line;
+                return (<LinePropertyGridComponent line={line}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
             if (entity._host) {
             if (entity._host) {
                 const control = entity as Control;
                 const control = entity as Control;
                 return (<ControlPropertyGridComponent control={control}
                 return (<ControlPropertyGridComponent control={control}

+ 4 - 4
inspector/src/components/actionTabs/tabs/propertyGrids/gridPropertyGridComponent.tsx

@@ -18,7 +18,7 @@ export class GridPropertyGridComponent extends React.Component<IGridPropertyGrid
         const scene = BABYLON.UtilityLayerRenderer.DefaultKeepDepthUtilityLayer.utilityLayerScene;
         const scene = BABYLON.UtilityLayerRenderer.DefaultKeepDepthUtilityLayer.utilityLayerScene;
 
 
         for (var mesh of scene.meshes) {
         for (var mesh of scene.meshes) {
-            if (mesh.metadata && mesh.metadata.isInspectorGrid) {
+            if (mesh.reservedDataStore && mesh.reservedDataStore.isInspectorGrid) {
                 this._gridMesh = mesh;
                 this._gridMesh = mesh;
                 this.setState({ isEnabled: true });
                 this.setState({ isEnabled: true });
                 return;
                 return;
@@ -43,12 +43,12 @@ export class GridPropertyGridComponent extends React.Component<IGridPropertyGrid
             var depth = (extend.max.z - extend.min.z) * 5.0;
             var depth = (extend.max.z - extend.min.z) * 5.0;
 
 
             this._gridMesh = BABYLON.Mesh.CreateGround("grid", 1.0, 1.0, 1, scene);
             this._gridMesh = BABYLON.Mesh.CreateGround("grid", 1.0, 1.0, 1, scene);
-            if (!this._gridMesh.metadata) {
-                this._gridMesh.metadata = {};
+            if (!this._gridMesh.reservedDataStore) {
+                this._gridMesh.reservedDataStore = {};
             }
             }
             this._gridMesh.scaling.x = Math.max(width, depth);
             this._gridMesh.scaling.x = Math.max(width, depth);
             this._gridMesh.scaling.z = this._gridMesh.scaling.x;
             this._gridMesh.scaling.z = this._gridMesh.scaling.x;
-            this._gridMesh.metadata.isInspectorGrid = true;
+            this._gridMesh.reservedDataStore.isInspectorGrid = true;
             this._gridMesh.isPickable = false;
             this._gridMesh.isPickable = false;
 
 
             var groundMaterial = new (BABYLON as any).GridMaterial("GridMaterial", scene);
             var groundMaterial = new (BABYLON as any).GridMaterial("GridMaterial", scene);

+ 35 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/checkboxPropertyGridComponent.tsx

@@ -0,0 +1,35 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { Checkbox } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+
+interface ICheckboxPropertyGridComponentProps {
+    checkbox: Checkbox,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class CheckboxPropertyGridComponent extends React.Component<ICheckboxPropertyGridComponentProps> {
+    constructor(props: ICheckboxPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const checkbox = this.props.checkbox;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={checkbox} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="CHECKBOX">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Check size ratio" target={checkbox} propertyName="checkSizeRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Checked" target={checkbox} propertyName="isChecked" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 25 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx

@@ -8,6 +8,7 @@ import { SliderLineComponent } from "../../../lines/sliderLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { LockObject } from "../lockObject";
 import { LockObject } from "../lockObject";
+import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
 
 
 interface ICommonControlPropertyGridComponentProps {
 interface ICommonControlPropertyGridComponentProps {
     control: Control,
     control: Control,
@@ -23,13 +24,35 @@ export class CommonControlPropertyGridComponent extends React.Component<ICommonC
     render() {
     render() {
         const control = this.props.control;
         const control = this.props.control;
 
 
+        var horizontalOptions = [
+            { label: "Left", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT },
+            { label: "Right", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT },
+            { label: "Center", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER },
+        ];
+
+        var verticalOptions = [
+            { label: "Top", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP },
+            { label: "Bottom", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM },
+            { label: "Center", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER },
+        ];
+
         return (
         return (
             <div>
             <div>
                 <LineContainerComponent title="GENERAL">
                 <LineContainerComponent title="GENERAL">
                     <TextLineComponent label="Class" value={control.getClassName()} />
                     <TextLineComponent label="Class" value={control.getClassName()} />
                     <SliderLineComponent label="Alpha" target={control} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Alpha" target={control} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <TextInputLineComponent lockObject={this.props.lockObject} label="Color" target={control} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <TextInputLineComponent lockObject={this.props.lockObject} label="Background" target={control} propertyName="background" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    {
+                        control.color &&
+                        <TextInputLineComponent lockObject={this.props.lockObject} label="Color" target={control} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
+                    {
+                        (control as any).background &&
+                        <TextInputLineComponent lockObject={this.props.lockObject} label="Background" target={control} propertyName="background" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
+                </LineContainerComponent>
+                <LineContainerComponent title="ALIGNMENT">
+                    <OptionsLineComponent label="Horizontal" options={horizontalOptions} target={control} propertyName="horizontalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <OptionsLineComponent label="Vertical" options={verticalOptions} target={control} propertyName="verticalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 </LineContainerComponent>
                 <LineContainerComponent title="POSITION">
                 <LineContainerComponent title="POSITION">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Left" target={control} propertyName="left" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Left" target={control} propertyName="left" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 33 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/ellipsePropertyGridComponent.tsx

@@ -0,0 +1,33 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { Ellipse } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+
+interface IEllipsePropertyGridComponentProps {
+    ellipse: Ellipse,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class EllipsePropertyGridComponent extends React.Component<IEllipsePropertyGridComponentProps> {
+    constructor(props: IEllipsePropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const ellipse = this.props.ellipse;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={ellipse} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="ELLIPSE">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={ellipse} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 42 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/imageBasedSliderPropertyGridComponent.tsx

@@ -0,0 +1,42 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { LockObject } from "../lockObject";
+import { ImageBasedSlider } from "babylonjs-gui";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+
+interface IImageBasedSliderPropertyGridComponentProps {
+    imageBasedSlider: ImageBasedSlider,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class ImageBasedSliderPropertyGridComponent extends React.Component<IImageBasedSliderPropertyGridComponentProps> {
+    constructor(props: IImageBasedSliderPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const imageBasedSlider = this.props.imageBasedSlider;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={imageBasedSlider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="IMAGE BASED SLIDER">
+                    <CheckBoxLineComponent label="Display thumb" target={imageBasedSlider} propertyName="displayThumb" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Vertical" target={imageBasedSlider} propertyName="isVertical" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Thumb clamped" target={imageBasedSlider} propertyName="isThumbClamped" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Bar offset" target={imageBasedSlider} propertyName="barOffset" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Thumb width" target={imageBasedSlider} propertyName="thumbWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Minimum" target={imageBasedSlider} propertyName="minimum" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Maximum" target={imageBasedSlider} propertyName="maximum" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Value" target={imageBasedSlider} propertyName="value" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 52 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx

@@ -0,0 +1,52 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { LockObject } from "../lockObject";
+import { Image } from "babylonjs-gui";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+
+interface IImagePropertyGridComponentProps {
+    image: Image,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class ImagePropertyGridComponent extends React.Component<IImagePropertyGridComponentProps> {
+    constructor(props: IImagePropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const image = this.props.image;
+
+        var stretchOptions = [
+            { label: "None", value: BABYLON.GUI.Image.STRETCH_NONE },
+            { label: "Fill", value: BABYLON.GUI.Image.STRETCH_FILL },
+            { label: "Uniform", value: BABYLON.GUI.Image.STRETCH_UNIFORM },
+            { label: "Extend", value: BABYLON.GUI.Image.STRETCH_EXTEND }
+        ];
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={image} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="IMAGE">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Source left" target={image} propertyName="sourceLeft" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Source top" target={image} propertyName="sourceTop" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Source width" target={image} propertyName="sourceWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Source height" target={image} propertyName="sourceHeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Autoscale" target={image} propertyName="autoScale" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <OptionsLineComponent label="Stretch" options={stretchOptions} target={image} propertyName="stretch" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={value => this.setState({ mode: value })} />
+                </LineContainerComponent>
+                <LineContainerComponent title="ANIMATION SHEET">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Cell Id" isInteger={true} target={image} propertyName="cellId" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Cell width" target={image} propertyName="cellWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Cell height" target={image} propertyName="cellHeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 55 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/linePropertyGridComponent.tsx

@@ -0,0 +1,55 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { Line } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+
+interface ILinePropertyGridComponentProps {
+    line: Line,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class LinePropertyGridComponent extends React.Component<ILinePropertyGridComponentProps> {
+    constructor(props: ILinePropertyGridComponentProps) {
+        super(props);
+    }
+
+    onDashChange(value: string) {
+        const line = this.props.line;
+        const split = value.split(",");
+        line.dash = [];
+
+        split.forEach(v => {
+            const int = parseInt(v);
+
+            if (isNaN(int)) {
+                return;
+            }
+
+            line.dash.push(int);
+        });
+    }
+
+    render() {
+        const line = this.props.line;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={line} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="LINE">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Line width" target={line} propertyName="lineWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="X1" target={line} propertyName="x1" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Y1" target={line} propertyName="y1" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="X2" target={line} propertyName="x2" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Y2" target={line} propertyName="y2" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Dash pattern" target={line} value={line.dash.join(",")} onChange={newValue => this.onDashChange(newValue)} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 38 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/radioButtonPropertyGridComponent.tsx

@@ -0,0 +1,38 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { RadioButton } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+
+interface IRadioButtonPropertyGridComponentProps {
+    radioButton: RadioButton,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class RadioButtonPropertyGridComponent extends React.Component<IRadioButtonPropertyGridComponentProps> {
+    constructor(props: IRadioButtonPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const radioButton = this.props.radioButton;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={radioButton} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="RADIO BUTTON">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={radioButton} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Check size ratio" target={radioButton} propertyName="checkSizeRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Group" target={radioButton} propertyName="group" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Checked" target={radioButton} propertyName="isChecked" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 34 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/rectanglePropertyGridComponent.tsx

@@ -0,0 +1,34 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { Rectangle } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+
+interface IRectanglePropertyGridComponentProps {
+    rectangle: Rectangle,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class RectanglePropertyGridComponent extends React.Component<IRectanglePropertyGridComponentProps> {
+    constructor(props: IRectanglePropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const rectangle = this.props.rectangle;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={rectangle} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="RECTANGLE">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={rectangle} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Corner radius" target={rectangle} propertyName="cornerRadius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 44 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/sliderPropertyGridComponent.tsx

@@ -0,0 +1,44 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { LockObject } from "../lockObject";
+import { Slider } from "babylonjs-gui";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+
+interface ISliderPropertyGridComponentProps {
+    slider: Slider,
+    lockObject: LockObject,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class SliderPropertyGridComponent extends React.Component<ISliderPropertyGridComponentProps> {
+    constructor(props: ISliderPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const slider = this.props.slider;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={slider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="SLIDER">
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Border color" target={slider} propertyName="borderColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Display thumb" target={slider} propertyName="displayThumb" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Thumb circle" target={slider} propertyName="isThumbCircle" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Vertical" target={slider} propertyName="isVertical" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Thumb clamped" target={slider} propertyName="isThumbClamped" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Bar offset" target={slider} propertyName="barOffset" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent lockObject={this.props.lockObject} label="Thumb width" target={slider} propertyName="thumbWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Minimum" target={slider} propertyName="minimum" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Maximum" target={slider} propertyName="maximum" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Value" target={slider} propertyName="value" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 15 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx

@@ -6,6 +6,7 @@ import { TextBlock } from "babylonjs-gui";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { LockObject } from "../lockObject";
 import { LockObject } from "../lockObject";
+import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
 
 
 interface ITextBlockPropertyGridComponentProps {
 interface ITextBlockPropertyGridComponentProps {
     textBlock: TextBlock,
     textBlock: TextBlock,
@@ -21,11 +22,25 @@ export class TextBlockPropertyGridComponent extends React.Component<ITextBlockPr
     render() {
     render() {
         const textBlock = this.props.textBlock;
         const textBlock = this.props.textBlock;
 
 
+        var horizontalOptions = [
+            { label: "Left", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT },
+            { label: "Right", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT },
+            { label: "Center", value: BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER },
+        ];
+
+        var verticalOptions = [
+            { label: "Top", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP },
+            { label: "Bottom", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM },
+            { label: "Center", value: BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER },
+        ];
+
         return (
         return (
             <div className="pane">
             <div className="pane">
                 <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <LineContainerComponent title="TEXTBLOCK">
                 <LineContainerComponent title="TEXTBLOCK">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Text" target={textBlock} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Text" target={textBlock} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <OptionsLineComponent label="Horizontal text alignment" options={horizontalOptions} target={textBlock} propertyName="textHorizontalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <OptionsLineComponent label="Vertical text alignment" options={verticalOptions} target={textBlock} propertyName="textVerticalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 </LineContainerComponent>
             </div>
             </div>
         );
         );

+ 13 - 13
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/axesViewerComponent.tsx

@@ -11,23 +11,23 @@ export class AxesViewerComponent extends React.Component<IAxisViewerComponentPro
         super(props);
         super(props);
         const node = this.props.node;
         const node = this.props.node;
 
 
-        if (!node.metadata) {
-            node.metadata = {};
+        if (!node.reservedDataStore) {
+            node.reservedDataStore = {};
         }
         }
 
 
-        this.state = { displayAxis: (node.metadata && node.metadata.axisViewer) ? true : false }
+        this.state = { displayAxis: (node.reservedDataStore && node.reservedDataStore.axisViewer) ? true : false }
     }
     }
 
 
     displayAxes() {
     displayAxes() {
         const node = this.props.node;
         const node = this.props.node;
         const scene = node.getScene();
         const scene = node.getScene();
 
 
-        if (node.metadata.axisViewer) {
-            node.metadata.axisViewer.dispose();
-            node.metadata.axisViewer = null;
+        if (node.reservedDataStore.axisViewer) {
+            node.reservedDataStore.axisViewer.dispose();
+            node.reservedDataStore.axisViewer = null;
 
 
-            scene.onBeforeRenderObservable.remove(node.metadata.onBeforeRenderObserver);
-            node.metadata.onBeforeRenderObserver = null;
+            scene.onBeforeRenderObservable.remove(node.reservedDataStore.onBeforeRenderObserver);
+            node.reservedDataStore.onBeforeRenderObserver = null;
 
 
             this.setState({ displayAxis: false });
             this.setState({ displayAxis: false });
 
 
@@ -35,16 +35,16 @@ export class AxesViewerComponent extends React.Component<IAxisViewerComponentPro
         }
         }
 
 
         const viewer = new BABYLON.Debug.AxesViewer(scene);
         const viewer = new BABYLON.Debug.AxesViewer(scene);
-        node.metadata.axisViewer = viewer;
+        node.reservedDataStore.axisViewer = viewer;
         const x = new BABYLON.Vector3(1, 0, 0);
         const x = new BABYLON.Vector3(1, 0, 0);
         const y = new BABYLON.Vector3(0, 1, 0);
         const y = new BABYLON.Vector3(0, 1, 0);
         const z = new BABYLON.Vector3(0, 0, 1);
         const z = new BABYLON.Vector3(0, 0, 1);
 
 
-        viewer.xAxisMesh!.metadata = { hidden: true };
-        viewer.yAxisMesh!.metadata = { hidden: true };
-        viewer.zAxisMesh!.metadata = { hidden: true };
+        viewer.xAxisMesh!.reservedDataStore = { hidden: true };
+        viewer.yAxisMesh!.reservedDataStore = { hidden: true };
+        viewer.zAxisMesh!.reservedDataStore = { hidden: true };
 
 
-        node.metadata.onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {
+        node.reservedDataStore.onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {
             let matrix = node.getWorldMatrix();
             let matrix = node.getWorldMatrix();
             let extend = BABYLON.Tmp.Vector3[0];
             let extend = BABYLON.Tmp.Vector3[0];
             const worldExtend = scene.getWorldExtends();
             const worldExtend = scene.getWorldExtends();

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

@@ -23,16 +23,16 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         super(props);
         super(props);
         const mesh = this.props.mesh;
         const mesh = this.props.mesh;
 
 
-        this.state = { displayNormals: false, renderNormalVectors: mesh.metadata && mesh.metadata.normalLines }
+        this.state = { displayNormals: false, renderNormalVectors: mesh.reservedDataStore && mesh.reservedDataStore.normalLines }
     }
     }
 
 
     renderNormalVectors() {
     renderNormalVectors() {
         const mesh = this.props.mesh;
         const mesh = this.props.mesh;
         const scene = mesh.getScene();
         const scene = mesh.getScene();
 
 
-        if (mesh.metadata && mesh.metadata.normalLines) {
-            mesh.metadata.normalLines.dispose();
-            mesh.metadata.normalLines = null;
+        if (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) {
+            mesh.reservedDataStore.normalLines.dispose();
+            mesh.reservedDataStore.normalLines = null;
 
 
             this.setState({ renderNormalVectors: false });
             this.setState({ renderNormalVectors: false });
             return;
             return;
@@ -55,11 +55,11 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         normalLines.color = color;
         normalLines.color = color;
         normalLines.parent = mesh;
         normalLines.parent = mesh;
 
 
-        if (!mesh.metadata) {
-            mesh.metadata = {};
+        if (!mesh.reservedDataStore) {
+            mesh.reservedDataStore = {};
         }
         }
 
 
-        mesh.metadata.normalLines = normalLines;
+        mesh.reservedDataStore.normalLines = normalLines;
 
 
         this.setState({ renderNormalVectors: true });
         this.setState({ renderNormalVectors: true });
     }
     }
@@ -74,8 +74,8 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         if (mesh.material.getClassName() === "NormalMaterial") {
         if (mesh.material.getClassName() === "NormalMaterial") {
             mesh.material.dispose();
             mesh.material.dispose();
 
 
-            mesh.material = mesh.metadata.originalMaterial;
-            mesh.metadata.originalMaterial = null;
+            mesh.material = mesh.reservedDataStore.originalMaterial;
+            mesh.reservedDataStore.originalMaterial = null;
             this.setState({ displayNormals: false });
             this.setState({ displayNormals: false });
         } else {
         } else {
 
 
@@ -87,15 +87,15 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                 return;
                 return;
             }
             }
 
 
-            if (!mesh.metadata) {
-                mesh.metadata = {};
+            if (!mesh.reservedDataStore) {
+                mesh.reservedDataStore = {};
             }
             }
 
 
-            mesh.metadata.originalMaterial = mesh.material;
+            mesh.reservedDataStore.originalMaterial = mesh.material;
             const normalMaterial = new (BABYLON as any).NormalMaterial("normalMaterial", scene);
             const normalMaterial = new (BABYLON as any).NormalMaterial("normalMaterial", scene);
             normalMaterial.disableLighting = true;
             normalMaterial.disableLighting = true;
             normalMaterial.sideOrientation = mesh.material.sideOrientation;
             normalMaterial.sideOrientation = mesh.material.sideOrientation;
-            normalMaterial.metadata = { hidden: true };
+            normalMaterial.reservedDataStore = { hidden: true };
             mesh.material = normalMaterial;
             mesh.material = normalMaterial;
             this.setState({ displayNormals: true });
             this.setState({ displayNormals: true });
         }
         }
@@ -139,7 +139,7 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         const scene = mesh.getScene();
         const scene = mesh.getScene();
 
 
         const displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
         const displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
-        const renderNormalVectors = (mesh.metadata && mesh.metadata.normalLines) ? true : false;
+        const renderNormalVectors = (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) ? true : false;
 
 
         return (
         return (
             <div className="pane">
             <div className="pane">

+ 24 - 24
inspector/src/components/sceneExplorer/entities/meshTreeItemComponent.tsx

@@ -19,7 +19,7 @@ export class MeshTreeItemComponent extends React.Component<IMeshTreeItemComponen
 
 
         const mesh = this.props.mesh;
         const mesh = this.props.mesh;
 
 
-        this.state = { isGizmoEnabled: mesh.metadata && mesh.metadata.gizmo, isVisible: this.props.mesh.isVisible }
+        this.state = { isGizmoEnabled: mesh.reservedDataStore && mesh.reservedDataStore.gizmo, isVisible: this.props.mesh.isVisible }
     }
     }
 
 
     showGizmos(): void {
     showGizmos(): void {
@@ -27,60 +27,60 @@ export class MeshTreeItemComponent extends React.Component<IMeshTreeItemComponen
 
 
         if (!this.state.isGizmoEnabled) {
         if (!this.state.isGizmoEnabled) {
 
 
-            if (!mesh.metadata) {
-                mesh.metadata = {};
+            if (!mesh.reservedDataStore) {
+                mesh.reservedDataStore = {};
             }
             }
-            mesh.metadata.previousParent = mesh.parent;
+            mesh.reservedDataStore.previousParent = mesh.parent;
 
 
-            if (mesh.metadata.previousParent) {
-                if (!mesh.metadata.previousParent.metadata) {
-                    mesh.metadata.previousParent.metadata = {};
+            if (mesh.reservedDataStore.previousParent) {
+                if (!mesh.reservedDataStore.previousParent.reservedDataStore) {
+                    mesh.reservedDataStore.previousParent.reservedDataStore = {};
                 }
                 }
 
 
-                if (!mesh.metadata.previousParent.metadata.detachedChildren) {
-                    mesh.metadata.previousParent.metadata.detachedChildren = [];
+                if (!mesh.reservedDataStore.previousParent.reservedDataStore.detachedChildren) {
+                    mesh.reservedDataStore.previousParent.reservedDataStore.detachedChildren = [];
                 }
                 }
 
 
-                mesh.metadata.previousParent.metadata.detachedChildren.push(mesh);
+                mesh.reservedDataStore.previousParent.reservedDataStore.detachedChildren.push(mesh);
             }
             }
 
 
             // Connect to gizmo
             // Connect to gizmo
             const dummy = BABYLON.BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox(mesh as Mesh);
             const dummy = BABYLON.BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox(mesh as Mesh);
-            dummy.metadata = { hidden: true };
+            dummy.reservedDataStore = { hidden: true };
             const gizmo = new BABYLON.BoundingBoxGizmo(BABYLON.Color3.FromHexString("#0984e3"));
             const gizmo = new BABYLON.BoundingBoxGizmo(BABYLON.Color3.FromHexString("#0984e3"));
             gizmo.attachedMesh = dummy;
             gizmo.attachedMesh = dummy;
 
 
             gizmo.updateBoundingBox();
             gizmo.updateBoundingBox();
 
 
             gizmo.fixedDragMeshScreenSize = true;
             gizmo.fixedDragMeshScreenSize = true;
-            mesh.metadata.gizmo = gizmo;
+            mesh.reservedDataStore.gizmo = gizmo;
 
 
             var pointerDragBehavior = new BABYLON.PointerDragBehavior();
             var pointerDragBehavior = new BABYLON.PointerDragBehavior();
             pointerDragBehavior.useObjectOrienationForDragging = false;
             pointerDragBehavior.useObjectOrienationForDragging = false;
 
 
             dummy.addBehavior(pointerDragBehavior);
             dummy.addBehavior(pointerDragBehavior);
 
 
-            mesh.metadata.pointerDragBehavior = pointerDragBehavior;
-            mesh.metadata.dummy = dummy;
+            mesh.reservedDataStore.pointerDragBehavior = pointerDragBehavior;
+            mesh.reservedDataStore.dummy = dummy;
 
 
             this.setState({ isGizmoEnabled: true });
             this.setState({ isGizmoEnabled: true });
             return;
             return;
         }
         }
 
 
-        const previousParent = mesh.metadata.previousParent;
-        mesh.removeBehavior(mesh.metadata.pointerDragBehavior);
-        mesh.metadata.gizmo.dispose();
-        mesh.metadata.gizmo = null;
+        const previousParent = mesh.reservedDataStore.previousParent;
+        mesh.removeBehavior(mesh.reservedDataStore.pointerDragBehavior);
+        mesh.reservedDataStore.gizmo.dispose();
+        mesh.reservedDataStore.gizmo = null;
         mesh.setParent(previousParent);
         mesh.setParent(previousParent);
-        mesh.metadata.dummy.dispose();
-        mesh.metadata.dummy = null;
+        mesh.reservedDataStore.dummy.dispose();
+        mesh.reservedDataStore.dummy = null;
 
 
-        if (previousParent && previousParent.metadata) {
-            previousParent.metadata.detachedChildren = null;
+        if (previousParent && previousParent.reservedDataStore) {
+            previousParent.reservedDataStore.detachedChildren = null;
         }
         }
 
 
-        mesh.metadata.previousParent = null;
-        mesh.metadata.pointerDragBehavior = null;
+        mesh.reservedDataStore.previousParent = null;
+        mesh.reservedDataStore.pointerDragBehavior = null;
 
 
         this.setState({ isGizmoEnabled: false });
         this.setState({ isGizmoEnabled: false });
     }
     }

+ 10 - 10
inspector/src/components/sceneExplorer/entities/sceneTreeItemComponent.tsx

@@ -22,8 +22,8 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
 
 
         const scene = this.props.scene;
         const scene = this.props.scene;
         let gizmoMode = 0;
         let gizmoMode = 0;
-        if (scene.metadata && scene.metadata.gizmoManager) {
-            const manager: GizmoManager = scene.metadata.gizmoManager;
+        if (scene.reservedDataStore && scene.reservedDataStore.gizmoManager) {
+            const manager: GizmoManager = scene.reservedDataStore.gizmoManager;
             if (manager.positionGizmoEnabled) {
             if (manager.positionGizmoEnabled) {
                 gizmoMode = 1;
                 gizmoMode = 1;
             } else if (manager.rotationGizmoEnabled) {
             } else if (manager.rotationGizmoEnabled) {
@@ -57,8 +57,8 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
         const scene = this.props.scene;
         const scene = this.props.scene;
         this._onSelectionChangeObserver = this.props.onSelectionChangedObservable.add((entity) => {
         this._onSelectionChangeObserver = this.props.onSelectionChangedObservable.add((entity) => {
             this._selectedEntity = entity;
             this._selectedEntity = entity;
-            if (scene.metadata && scene.metadata.gizmoManager) {
-                const manager: GizmoManager = scene.metadata.gizmoManager;
+            if (scene.reservedDataStore && scene.reservedDataStore.gizmoManager) {
+                const manager: GizmoManager = scene.reservedDataStore.gizmoManager;
 
 
                 const className = entity.getClassName();
                 const className = entity.getClassName();
 
 
@@ -115,15 +115,15 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
     setGizmoMode(mode: number) {
     setGizmoMode(mode: number) {
         const scene = this.props.scene;
         const scene = this.props.scene;
 
 
-        if (!scene.metadata) {
-            scene.metadata = {};
+        if (!scene.reservedDataStore) {
+            scene.reservedDataStore = {};
         }
         }
 
 
-        if (!scene.metadata.gizmoManager) {
-            scene.metadata.gizmoManager = new GizmoManager(scene);
+        if (!scene.reservedDataStore.gizmoManager) {
+            scene.reservedDataStore.gizmoManager = new GizmoManager(scene);
         }
         }
 
 
-        const manager: GizmoManager = scene.metadata.gizmoManager;
+        const manager: GizmoManager = scene.reservedDataStore.gizmoManager;
 
 
         manager.positionGizmoEnabled = false;
         manager.positionGizmoEnabled = false;
         manager.rotationGizmoEnabled = false;
         manager.rotationGizmoEnabled = false;
@@ -132,7 +132,7 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
         if (this.state.gizmoMode === mode) {
         if (this.state.gizmoMode === mode) {
             mode = 0;
             mode = 0;
             manager.dispose();
             manager.dispose();
-            scene.metadata.gizmoManager = null;
+            scene.reservedDataStore.gizmoManager = null;
         } else {
         } else {
             switch (mode) {
             switch (mode) {
                 case 1:
                 case 1:

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

@@ -126,7 +126,7 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
                 data.previousOne = item;
                 data.previousOne = item;
             }
             }
 
 
-            if (item.getChildren && item.metadata && item.metadata.isExpanded) {
+            if (item.getChildren && item.reservedDataStore && item.reservedDataStore.isExpanded) {
                 if (this.findSiblings(item, item.getChildren(), target, goNext, data)) {
                 if (this.findSiblings(item, item.getChildren(), target, goNext, data)) {
                     return true;
                     return true;
                 }
                 }
@@ -152,16 +152,16 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
             goNext = true;
             goNext = true;
             search = true;
             search = true;
         } else if (keyEvent.keyCode === 13 || keyEvent.keyCode === 39) { // enter or right
         } else if (keyEvent.keyCode === 13 || keyEvent.keyCode === 39) { // enter or right
-            var metadata = this.state.selectedEntity.metadata;
-            if (metadata && metadata.setExpandedState) {
-                metadata.setExpandedState(true);
+            var reservedDataStore = this.state.selectedEntity.reservedDataStore;
+            if (reservedDataStore && reservedDataStore.setExpandedState) {
+                reservedDataStore.setExpandedState(true);
             }
             }
             keyEvent.preventDefault();
             keyEvent.preventDefault();
             return;
             return;
         } else if (keyEvent.keyCode === 37) { // left
         } else if (keyEvent.keyCode === 37) { // left
-            var metadata = this.state.selectedEntity.metadata;
-            if (metadata && metadata.setExpandedState) {
-                metadata.setExpandedState(false);
+            var reservedDataStore = this.state.selectedEntity.reservedDataStore;
+            if (reservedDataStore && reservedDataStore.setExpandedState) {
+                reservedDataStore.setExpandedState(false);
             }
             }
             keyEvent.preventDefault();
             keyEvent.preventDefault();
             return;
             return;

+ 2 - 2
inspector/src/components/sceneExplorer/treeItemComponent.tsx

@@ -30,7 +30,7 @@ class TreeItemExpandableHeaderComponent extends React.Component<ITreeItemExpanda
                 <div className="text">
                 <div className="text">
                     <div className="arrow icon" onClick={() => this.props.onClick()}>
                     <div className="arrow icon" onClick={() => this.props.onClick()}>
                         {chevron}
                         {chevron}
-                    </div> 
+                    </div>
                     <div className="text-value">
                     <div className="text-value">
                         {this.props.label}
                         {this.props.label}
                     </div>
                     </div>
@@ -113,7 +113,7 @@ export class TreeItemComponent extends React.Component<ITreeItemComponentProps,
     }
     }
 
 
     expandAll(expand: boolean) {
     expandAll(expand: boolean) {
-        this.setState({isExpanded: expand, mustExpand: expand});
+        this.setState({ isExpanded: expand, mustExpand: expand });
     }
     }
 
 
     render() {
     render() {

+ 4 - 4
inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx

@@ -108,14 +108,14 @@ export class TreeItemSelectableComponent extends React.Component<ITreeItemSelect
         const children = Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
         const children = Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
         const hasChildren = children.length > 0;
         const hasChildren = children.length > 0;
 
 
-        if (!entity.metadata) {
-            entity.metadata = {};
+        if (!entity.reservedDataStore) {
+            entity.reservedDataStore = {};
         }
         }
 
 
-        entity.metadata.setExpandedState = (value: boolean) => {
+        entity.reservedDataStore.setExpandedState = (value: boolean) => {
             this.setState({ isExpanded: value });
             this.setState({ isExpanded: value });
         }
         }
-        entity.metadata.isExpanded = this.state.isExpanded;
+        entity.reservedDataStore.isExpanded = this.state.isExpanded;
 
 
         if (this.props.filter) {
         if (this.props.filter) {
             const lowerCaseFilter = this.props.filter.toLowerCase();
             const lowerCaseFilter = this.props.filter.toLowerCase();

+ 3 - 3
inspector/src/tools.ts

@@ -21,10 +21,10 @@ export class Tools {
             return [];
             return [];
         }
         }
 
 
-        const finalArray = items.filter((i) => !i.metadata || !i.metadata.hidden);
+        const finalArray = items.filter((i) => !i.reservedDataStore || !i.reservedDataStore.hidden);
 
 
-        if (parent && parent.metadata && parent.metadata.detachedChildren) {
-            finalArray.push(...parent.metadata.detachedChildren);
+        if (parent && parent.reservedDataStore && parent.reservedDataStore.detachedChildren) {
+            finalArray.push(...parent.reservedDataStore.detachedChildren);
         }
         }
 
 
         return finalArray.sort((a: any, b: any) => {
         return finalArray.sort((a: any, b: any) => {

+ 6 - 4
sandbox/index.js

@@ -316,17 +316,19 @@ if (BABYLON.Engine.isSupported()) {
         if (event.keyCode === 32 && event.target.nodeName !== "INPUT") {
         if (event.keyCode === 32 && event.target.nodeName !== "INPUT") {
             if (footer.style.display === "none") {
             if (footer.style.display === "none") {
                 footer.style.display = "block";
                 footer.style.display = "block";
-                canvas.style.height = "calc(100% - 56px)";
+                canvasZone.style.height = "calc(100% - 56px)";
+                if (debugLayerEnabled) {
+                    currentScene.debugLayer.show();
+                }
                 engine.resize();
                 engine.resize();
             }
             }
             else {
             else {
                 footer.style.display = "none";
                 footer.style.display = "none";
-                canvas.style.height = "100%";
+                canvasZone.style.height = "100%";
                 errorZone.style.display = "none";
                 errorZone.style.display = "none";
                 engine.resize();
                 engine.resize();
-                if (debugLayerEnabled) {
+                if (currentScene.debugLayer.isVisible()) {
                     currentScene.debugLayer.hide();
                     currentScene.debugLayer.hide();
-                    debugLayerEnabled = false;
                 }
                 }
             }
             }
         }
         }

+ 1 - 0
src/Cameras/babylon.camera.ts

@@ -1071,6 +1071,7 @@ module BABYLON {
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].minZ = this.minZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].maxZ = this.maxZ;
                 this._rigCameras[i].fov = this.fov;
                 this._rigCameras[i].fov = this.fov;
+                this._rigCameras[i].upVector.copyFrom(this.upVector);
             }
             }
 
 
             // only update viewport when ANAGLYPH
             // only update viewport when ANAGLYPH

+ 17 - 9
src/Cameras/babylon.targetCamera.ts

@@ -7,6 +7,7 @@ module BABYLON {
     export class TargetCamera extends Camera {
     export class TargetCamera extends Camera {
         private static _RigCamTransformMatrix = new Matrix();
         private static _RigCamTransformMatrix = new Matrix();
         private static _TargetTransformMatrix = new Matrix();
         private static _TargetTransformMatrix = new Matrix();
+        private static _TargetFocalPoint = new Vector3();
 
 
         /**
         /**
          * Define the current direction the camera is moving to
          * Define the current direction the camera is moving to
@@ -54,6 +55,8 @@ module BABYLON {
         /** @hidden */
         /** @hidden */
         public _currentTarget = Vector3.Zero();
         public _currentTarget = Vector3.Zero();
         /** @hidden */
         /** @hidden */
+        public _initialFocalDistance = 1;
+        /** @hidden */
         public _viewMatrix = Matrix.Zero();
         public _viewMatrix = Matrix.Zero();
         /** @hidden */
         /** @hidden */
         public _camMatrix = Matrix.Zero();
         public _camMatrix = Matrix.Zero();
@@ -213,6 +216,8 @@ module BABYLON {
         public setTarget(target: Vector3): void {
         public setTarget(target: Vector3): void {
             this.upVector.normalize();
             this.upVector.normalize();
 
 
+            this._initialFocalDistance = target.subtract(this.position).length();
+
             if (this.position.z === target.z) {
             if (this.position.z === target.z) {
                 this.position.z += Epsilon;
                 this.position.z += Epsilon;
             }
             }
@@ -446,11 +451,8 @@ module BABYLON {
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                     var leftSign = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var leftSign = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                     var rightSign = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
                     var rightSign = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft.position);
-                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
-
-                    camLeft.setTarget(this.getTarget());
-                    camRight.setTarget(this.getTarget());
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);
+                    this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);
                     break;
                     break;
 
 
                 case Camera.RIG_MODE_VR:
                 case Camera.RIG_MODE_VR:
@@ -469,15 +471,21 @@ module BABYLON {
             super._updateRigCameras();
             super._updateRigCameras();
         }
         }
 
 
-        private _getRigCamPosition(halfSpace: number, result: Vector3) {
+        private _getRigCamPositionAndTarget(halfSpace: number, rigCamera: TargetCamera) {
             var target = this.getTarget();
             var target = this.getTarget();
-            Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);
+
+            TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);
+            var newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);
+
+            Matrix.TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
             TargetCamera._TargetTransformMatrix.multiplyToRef(Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
-            Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            Matrix.TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);
 
 
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
             TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
 
 
-            Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
+            Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);
+            rigCamera.setTarget(newFocalTarget);
         }
         }
 
 
         /**
         /**

+ 30 - 25
src/Materials/Textures/babylon.baseTexture.ts

@@ -29,6 +29,11 @@ module BABYLON {
         @serialize()
         @serialize()
         public metadata: any = null;
         public metadata: any = null;
 
 
+        /**
+         * For internal use only. Please do not use.
+         */
+        public reservedDataStore: any = null;
+
         @serialize("hasAlpha")
         @serialize("hasAlpha")
         private _hasAlpha = false;
         private _hasAlpha = false;
         /**
         /**
@@ -296,8 +301,8 @@ module BABYLON {
         constructor(scene: Nullable<Scene>) {
         constructor(scene: Nullable<Scene>) {
             this._scene = scene || Engine.LastCreatedScene;
             this._scene = scene || Engine.LastCreatedScene;
             if (this._scene) {
             if (this._scene) {
-                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
                 this.uniqueId = this._scene.getUniqueId();
+                this._scene.addTexture(this);
             }
             }
             this._uid = null;
             this._uid = null;
         }
         }
@@ -399,30 +404,30 @@ module BABYLON {
             return new Size(this._texture.baseWidth, this._texture.baseHeight);
             return new Size(this._texture.baseWidth, this._texture.baseHeight);
         }
         }
 
 
-  /**
-         * Update the sampling mode of the texture.
-         * Default is Trilinear mode.
-         *
-         * | Value | Type               | Description |
-         * | ----- | ------------------ | ----------- |
-         * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |
-         * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |
-         * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |
-         * | 4     | NEAREST_NEAREST_MIPNEAREST |             |
-         * | 5    | NEAREST_LINEAR_MIPNEAREST |             |
-         * | 6    | NEAREST_LINEAR_MIPLINEAR |             |
-         * | 7    | NEAREST_LINEAR |             |
-         * | 8    | NEAREST_NEAREST |             |
-         * | 9   | LINEAR_NEAREST_MIPNEAREST |             |
-         * | 10   | LINEAR_NEAREST_MIPLINEAR |             |
-         * | 11   | LINEAR_LINEAR |             |
-         * | 12   | LINEAR_NEAREST |             |
-         *
-         *    > _mag_: magnification filter (close to the viewer)
-         *    > _min_: minification filter (far from the viewer)
-         *    > _mip_: filter used between mip map levels
-         *@param samplingMode Define the new sampling mode of the texture
-         */
+        /**
+               * Update the sampling mode of the texture.
+               * Default is Trilinear mode.
+               *
+               * | Value | Type               | Description |
+               * | ----- | ------------------ | ----------- |
+               * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |
+               * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |
+               * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |
+               * | 4     | NEAREST_NEAREST_MIPNEAREST |             |
+               * | 5    | NEAREST_LINEAR_MIPNEAREST |             |
+               * | 6    | NEAREST_LINEAR_MIPLINEAR |             |
+               * | 7    | NEAREST_LINEAR |             |
+               * | 8    | NEAREST_NEAREST |             |
+               * | 9   | LINEAR_NEAREST_MIPNEAREST |             |
+               * | 10   | LINEAR_NEAREST_MIPLINEAR |             |
+               * | 11   | LINEAR_LINEAR |             |
+               * | 12   | LINEAR_NEAREST |             |
+               *
+               *    > _mag_: magnification filter (close to the viewer)
+               *    > _min_: minification filter (far from the viewer)
+               *    > _mip_: filter used between mip map levels
+               *@param samplingMode Define the new sampling mode of the texture
+               */
         public updateSamplingMode(samplingMode: number): void {
         public updateSamplingMode(samplingMode: number): void {
             if (!this._texture) {
             if (!this._texture) {
                 return;
                 return;

+ 5 - 0
src/Materials/babylon.material.ts

@@ -382,6 +382,11 @@ module BABYLON {
         public metadata: any = null;
         public metadata: any = null;
 
 
         /**
         /**
+         * For internal use only. Please do not use.
+         */
+        public reservedDataStore: any = null;
+
+        /**
          * Specifies if the ready state should be checked on each call
          * Specifies if the ready state should be checked on each call
          */
          */
         @serialize()
         @serialize()

+ 1 - 4
src/Mesh/babylon.meshBuilder.ts

@@ -695,10 +695,7 @@ module BABYLON {
 
 
             if (options.sourcePlane) {
             if (options.sourcePlane) {
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
                 plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
-
-                const dot = BABYLON.Vector3.Dot(plane.position, options.sourcePlane.normal);
-                const flip = dot >= 0;
-                plane.lookAt(BABYLON.Vector3.Zero(), 0, flip ? Math.PI : 0, 0);
+                plane.setDirection(options.sourcePlane.normal);
             }
             }
 
 
             return plane;
             return plane;

+ 24 - 11
src/Mesh/babylon.transformNode.ts

@@ -455,17 +455,7 @@ module BABYLON {
             var dv = TransformNode._lookAtVectorCache;
             var dv = TransformNode._lookAtVectorCache;
             var pos = space === Space.LOCAL ? this.position : this.getAbsolutePosition();
             var pos = space === Space.LOCAL ? this.position : this.getAbsolutePosition();
             targetPoint.subtractToRef(pos, dv);
             targetPoint.subtractToRef(pos, dv);
-            var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
-            var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
-            var pitch = Math.atan2(dv.y, len);
-            if (this.rotationQuaternion) {
-                Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
-            }
-            else {
-                this.rotation.x = pitch + pitchCor;
-                this.rotation.y = yaw + yawCor;
-                this.rotation.z = rollCor;
-            }
+            this.setDirection(dv, yawCor, pitchCor, rollCor);
 
 
             // Correct for parent's rotation offset
             // Correct for parent's rotation offset
             if (space === Space.WORLD && this.parent) {
             if (space === Space.WORLD && this.parent) {
@@ -528,6 +518,29 @@ module BABYLON {
         }
         }
 
 
         /**
         /**
+         * Sets this transform node rotation to the given local axis.
+         * @param localAxis the axis in local space
+         * @param yawCor optional yaw (y-axis) correction in radians
+         * @param pitchCor optional pitch (x-axis) correction in radians
+         * @param rollCor optional roll (z-axis) correction in radians
+         * @returns this TransformNode
+         */
+        public setDirection(localAxis: Vector3, yawCor: number = 0, pitchCor: number = 0, rollCor: number = 0): TransformNode {
+            var yaw = -Math.atan2(localAxis.z, localAxis.x) - Math.PI / 2;
+            var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+            var pitch = Math.atan2(localAxis.y, len);
+            if (this.rotationQuaternion) {
+                Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
+            }
+            else {
+                this.rotation.x = pitch + pitchCor;
+                this.rotation.y = yaw + yawCor;
+                this.rotation.z = rollCor;
+            }
+            return this;
+        }
+
+        /**
          * Sets a new pivot point to the current node
          * Sets a new pivot point to the current node
          * @param point defines the new pivot point to use
          * @param point defines the new pivot point to use
          * @param space defines if the point is in world or local space (local by default)
          * @param space defines if the point is in world or local space (local by default)

+ 5 - 0
src/babylon.node.ts

@@ -69,6 +69,11 @@ module BABYLON {
         public metadata: any = null;
         public metadata: any = null;
 
 
         /**
         /**
+         * For internal use only. Please do not use.
+         */
+        public reservedDataStore: any = null;
+
+        /**
          * Gets or sets a boolean used to define if the node must be serialized
          * Gets or sets a boolean used to define if the node must be serialized
          */
          */
         public doNotSerialize = false;
         public doNotSerialize = false;

+ 6 - 0
src/babylon.scene.ts

@@ -276,6 +276,12 @@ module BABYLON {
          * Gets or sets user defined metadata
          * Gets or sets user defined metadata
          */
          */
         public metadata: any = null;
         public metadata: any = null;
+
+        /**
+         * For internal use only. Please do not use.
+         */
+        public reservedDataStore: any = null;
+
         /**
         /**
          * Gets the name of the plugin used to load this scene (null by default)
          * Gets the name of the plugin used to load this scene (null by default)
          */
          */

+ 0 - 5
tests/validation/config.json

@@ -37,11 +37,6 @@
       "referenceImage": "simulatePointer.png"
       "referenceImage": "simulatePointer.png"
     },
     },
     {
     {
-      "title": "Camera rig",
-      "playgroundId": "#ATL1CS#9",
-      "referenceImage": "cameraRig.png"
-    },
-    {
       "title": "Color Grading",
       "title": "Color Grading",
       "playgroundId": "#8EDB5N#2",
       "playgroundId": "#8EDB5N#2",
       "referenceImage": "colorGrading.png"
       "referenceImage": "colorGrading.png"

+ 0 - 1
what's new.md

@@ -204,7 +204,6 @@
 - Spring Joint could not be removed ([TrevorDev](https://github.com/TrevorDev))
 - Spring Joint could not be removed ([TrevorDev](https://github.com/TrevorDev))
 - Sometimes duplicate controller models are loaded in VR ([TrevorDev](https://github.com/TrevorDev))
 - Sometimes duplicate controller models are loaded in VR ([TrevorDev](https://github.com/TrevorDev))
 - Particle emit rate and start size over time do not reset on every particle system start ([TrevorDev](https://github.com/TrevorDev))
 - Particle emit rate and start size over time do not reset on every particle system start ([TrevorDev](https://github.com/TrevorDev))
-- Fix position and rotation of plane mesh created by MeshBuilder.CreatePlane when specifying a source plane ([sable](https://github.com/thscott))
 
 
 ### Core Engine
 ### Core Engine