Просмотр исходного кода

Removed inspector highlights for now

David Catuhe 8 лет назад
Родитель
Сommit
406da26a90
28 измененных файлов с 8007 добавлено и 7718 удалено
  1. 2773 2745
      dist/preview release/babylon.d.ts
  2. 38 38
      dist/preview release/babylon.js
  3. 181 64
      dist/preview release/babylon.max.js
  4. 2773 2745
      dist/preview release/babylon.module.d.ts
  5. 38 38
      dist/preview release/babylon.worker.js
  6. 889 861
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 29 29
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 181 64
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 889 861
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  10. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  11. 1 24
      dist/preview release/inspector/babylon.inspector.d.ts
  12. 0 86
      dist/preview release/inspector/babylon.inspector.js
  13. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  14. 1 8
      inspector/src/adapters/Adapter.ts
  15. 0 7
      inspector/src/adapters/LightAdapter.ts
  16. 0 13
      inspector/src/adapters/MaterialAdapter.ts
  17. 0 6
      inspector/src/adapters/MeshAdapter.ts
  18. 0 15
      inspector/src/tabs/PropertyTab.ts
  19. 0 6
      inspector/src/tabs/Tab.ts
  20. 0 15
      inspector/src/tabs/TextureTab.ts
  21. 0 23
      inspector/src/tree/TreeItem.ts
  22. 2 2
      src/Behaviors/Cameras/babylon.autoRotationBehavior.ts
  23. 6 6
      src/Behaviors/Cameras/babylon.bouncingBehavior.ts
  24. 178 51
      src/Behaviors/Cameras/babylon.framingBehavior.ts
  25. 5 1
      src/Cameras/babylon.arcRotateCamera.ts
  26. 9 0
      src/Culling/babylon.boundingInfo.ts
  27. 5 1
      src/Materials/babylon.material.ts
  28. 1 1
      src/Mesh/babylon.abstractMesh.ts

Разница между файлами не показана из-за своего большого размера
+ 2773 - 2745
dist/preview release/babylon.d.ts


Разница между файлами не показана из-за своего большого размера
+ 38 - 38
dist/preview release/babylon.js


+ 181 - 64
dist/preview release/babylon.max.js

@@ -11634,6 +11634,18 @@ var BABYLON;
                 return false;
             return this.boundingBox.isInFrustum(frustumPlanes);
         };
+        Object.defineProperty(BoundingInfo.prototype, "diagonalLength", {
+            /**
+             * Gets the world distance between the min and max points of the bounding box
+             */
+            get: function () {
+                var boundingBox = this.boundingBox;
+                var size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
+                return size.length();
+            },
+            enumerable: true,
+            configurable: true
+        });
         BoundingInfo.prototype.isCompletelyInFrustum = function (frustumPlanes) {
             return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
         };
@@ -25026,7 +25038,12 @@ var BABYLON;
         };
         Material.prototype._afterBind = function (mesh) {
             this._scene._cachedMaterial = this;
-            this._scene._cachedVisibility = mesh.visibility;
+            if (mesh) {
+                this._scene._cachedVisibility = mesh.visibility;
+            }
+            else {
+                this._scene._cachedVisibility = 1;
+            }
             this.onBindObservable.notifyObservers(mesh);
             if (this.disableDepthWrite) {
                 var engine = this._scene.getEngine();
@@ -34573,6 +34590,7 @@ var BABYLON;
             _this._viewMatrix = new BABYLON.Matrix();
             // Panning
             _this.panningAxis = new BABYLON.Vector3(1, 1, 0);
+            _this.onMeshTargetChangedObservable = new BABYLON.Observable();
             _this.checkCollisions = false;
             _this.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5);
             _this._previousPosition = BABYLON.Vector3.Zero();
@@ -35013,6 +35031,7 @@ var BABYLON;
                 }
                 this._targetHost = target;
                 this._target = this._getTargetPosition();
+                this.onMeshTargetChangedObservable.notifyObservers(this._targetHost);
             }
             else {
                 var newTarget = target;
@@ -35022,6 +35041,7 @@ var BABYLON;
                 }
                 this._target = newTarget;
                 this._targetBoundingCenter = null;
+                this.onMeshTargetChangedObservable.notifyObservers(null);
             }
             this.rebuildAnglesAndRadius();
         };
@@ -69678,16 +69698,14 @@ var BABYLON;
     var FramingBehavior = (function () {
         function FramingBehavior() {
             this._mode = FramingBehavior.IgnoreBoundsSizeMode;
-            this._radius = 0;
-            this._elevation = 0;
+            this._radiusOffset = 0;
+            this._elevation = 0.3;
             this._positionY = 0;
-            this._defaultElevation = 0;
-            this._elevationReturnTime = 2;
-            this._elevationReturnWaitTime = 0;
+            this._defaultElevation = 0.3;
+            this._elevationReturnTime = 1500;
+            this._elevationReturnWaitTime = 1000;
             this._zoomStopsAnimation = false;
-            this._framingTime = 1.0;
-            this._easingFunction = new BABYLON.ExponentialEase();
-            this._easingMode = BABYLON.EasingFunction.EASINGMODE_EASEINOUT;
+            this._framingTime = 1500;
             this._isPointerDown = false;
             this._lastFrameTime = null;
             this._lastInteractionTime = -Infinity;
@@ -69703,38 +69721,6 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(FramingBehavior.prototype, "easingFunction", {
-            /**
-             * Gets the easing function to use for transitions
-             */
-            get: function () {
-                return this._easingFunction;
-            },
-            /**
-             * Sets the easing function to use for transitions
-             */
-            set: function (value) {
-                this._easingFunction = value;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(FramingBehavior.prototype, "easingMode", {
-            /**
-             * Gets the easing function to use for transitions
-             */
-            get: function () {
-                return this._easingMode;
-            },
-            /**
-             * Sets the easing function to use for transitions
-             */
-            set: function (value) {
-                this._easingMode = value;
-            },
-            enumerable: true,
-            configurable: true
-        });
         Object.defineProperty(FramingBehavior.prototype, "mode", {
             /**
              * Gets current mode used by the behavior.
@@ -69751,31 +69737,31 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(FramingBehavior.prototype, "radius", {
+        Object.defineProperty(FramingBehavior.prototype, "radiusOffset", {
             /**
-             * Gets the radius of the camera relative to the framed model's bounding box.
+             * Gets the radius of the camera relative to the target's bounding box.
              */
             get: function () {
-                return this._radius;
+                return this._radiusOffset;
             },
             /**
-             * Sets the radius of the camera relative to the framed model's bounding box.
+             * Sets the radius of the camera relative to the target's bounding box.
              */
             set: function (radius) {
-                this._radius = radius;
+                this._radiusOffset = radius;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(FramingBehavior.prototype, "elevation", {
             /**
-             * Gets the elevation of the camera from the framed model, in radians.
+             * Gets the elevation of the camera from the target, in radians.
              */
             get: function () {
                 return this._elevation;
             },
             /**
-             * Sets the elevation of the camera from the framed model, in radians.
+             * Sets the elevation of the camera from the target, in radians.
              */
             set: function (elevation) {
                 this._elevation = elevation;
@@ -69896,6 +69882,11 @@ var BABYLON;
                     _this._isPointerDown = false;
                 }
             });
+            this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add(function (mesh) {
+                if (mesh) {
+                    _this.zoomOnMesh(mesh);
+                }
+            });
             this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(function () {
                 // Stop the animation if there is user interaction and the animation should stop for this interaction
                 _this._applyUserInteraction();
@@ -69908,6 +69899,97 @@ var BABYLON;
             var scene = this._attachedCamera.getScene();
             scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
             camera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+            camera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
+        };
+        /**
+         * Targets the given mesh and updates zoom level accordingly.
+         * @param mesh  The mesh to target.
+         * @param radius Optional. If a cached radius position already exists, overrides default.
+         * @param applyToLowerLimit Optional. Indicates if the calculated target radius should be applied to the
+         *		camera's lower radius limit too.
+         * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
+         * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
+         */
+        FramingBehavior.prototype.zoomOnMesh = function (mesh, radius, applyToLowerLimit, framingPositionY, focusOnOriginXZ) {
+            if (applyToLowerLimit === void 0) { applyToLowerLimit = false; }
+            if (focusOnOriginXZ === void 0) { focusOnOriginXZ = true; }
+            if (framingPositionY == null) {
+                framingPositionY = this._positionY;
+            }
+            // sets the radius and lower radius bounds
+            if (radius == null) {
+                // Small delta ensures camera is not always at lower zoom limit.
+                var delta = 0.1;
+                if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+                    var position = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+                    this._attachedCamera.lowerRadiusLimit = position - delta;
+                    radius = position;
+                }
+                else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                    radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+                }
+            }
+            var zoomTarget;
+            var zoomTargetY;
+            mesh.computeWorldMatrix(true);
+            var modelWorldPosition = new BABYLON.Vector3(0, 0, 0);
+            var modelWorldScale = new BABYLON.Vector3(0, 0, 0);
+            mesh.getWorldMatrix().decompose(modelWorldScale, new BABYLON.Quaternion(), modelWorldPosition);
+            //find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+            var bottom = modelWorldPosition.y + mesh.getBoundingInfo().minimum.y;
+            var top = modelWorldPosition.y + mesh.getBoundingInfo().maximum.y;
+            zoomTargetY = bottom + (top - bottom) * framingPositionY;
+            if (applyToLowerLimit) {
+                this._attachedCamera.lowerRadiusLimit = radius;
+            }
+            if (!this._radiusTransition) {
+                FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+                this._radiusTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
+            }
+            // transition to new radius
+            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime));
+            if (focusOnOriginXZ) {
+                zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
+            }
+            else {
+                zoomTarget = new BABYLON.Vector3(modelWorldPosition.x, zoomTargetY, modelWorldPosition.z);
+            }
+            // if (!this._vectorTransition) {
+            // 	FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+            // 	this._vectorTransition = Animation.CreateAnimation("target", Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
+            // }			
+            // this._animatables.push(Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 
+            // 						60, this._vectorTransition, this._framingTime));
+        };
+        /**
+         * Calculates the lowest radius for the camera based on the bounding box of the mesh.
+         * @param mesh The mesh on which to base the calculation. mesh boundingInfo used to estimate necessary
+         *			  frustum width.
+         * @param framingRadius An additional factor to add to the return camera radius.
+         * @return The minimum distance from the primary mesh's center point at which the camera must be kept in order
+         *		 to fully enclose the mesh in the viewing frustum.
+         */
+        FramingBehavior.prototype._calculateLowerRadiusFromModelBoundingSphere = function (mesh, framingRadius) {
+            var boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+            var frustumSlope = this._getFrustumSlope();
+            // Formula for setting distance
+            // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)
+            var radiusWithoutFraming = boxVectorGlobalDiagonal * 0.5;
+            // Horizon distance
+            var radius = radiusWithoutFraming * framingRadius;
+            var distanceForHorizontalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.x * frustumSlope.x));
+            var distanceForVerticalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.y * frustumSlope.y));
+            var distance = Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);
+            var camera = this._attachedCamera;
+            if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                // Don't exceed the requested limit
+                distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;
+            }
+            // Don't exceed the upper radius limit
+            if (camera.upperRadiusLimit) {
+                distance = distance > camera.upperRadiusLimit ? camera.upperRadiusLimit : distance;
+            }
+            return distance;
         };
         /**
          * Keeps the camera above the ground plane. If the user pulls the camera below the ground plane, the camera
@@ -69924,15 +70006,35 @@ var BABYLON;
                 //Transition to new position
                 this.stopAllAnimations();
                 if (!this._betaTransition) {
-                    this.easingFunction.setEasingMode(this.easingMode);
-                    this._betaTransition = BABYLON.Animation.CreateAnimation("beta", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, this.easingFunction);
+                    FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+                    this._betaTransition = BABYLON.Animation.CreateAnimation("beta", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
                 }
-                BABYLON.Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._betaTransition, this._elevationReturnTime, function () {
+                this._animatables.push(BABYLON.Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._betaTransition, this._elevationReturnTime, function () {
+                    _this._clearAnimationLocks();
                     _this.stopAllAnimations();
-                });
+                }));
             }
         };
         /**
+         * Returns the frustum slope based on the canvas ratio and camera FOV
+         * @returns The frustum slope represented as a Vector2 with X and Y slopes
+         */
+        FramingBehavior.prototype._getFrustumSlope = function () {
+            // Calculate the viewport ratio
+            // Aspect Ratio is Height/Width.
+            var camera = this._attachedCamera;
+            var engine = camera.getScene().getEngine();
+            var aspectRatio = engine.getAspectRatio(camera);
+            // Camera FOV is the vertical field of view (top-bottom) in radians.
+            // Slope of the frustum top/bottom planes in view space, relative to the forward vector.
+            var frustumSlopeY = Math.tan(camera.fov / 2);
+            // Slope of the frustum left/right planes in view space, relative to the forward vector.
+            // Provides the amount that one side (e.g. left) of the frustum gets wider for every unit
+            // along the forward vector.
+            var frustumSlopeX = frustumSlopeY / aspectRatio;
+            return new BABYLON.Vector2(frustumSlopeX, frustumSlopeY);
+        };
+        /**
          * Returns true if user is scrolling.
          * @return true if user is scrolling.
          */
@@ -69954,12 +70056,19 @@ var BABYLON;
             return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
         };
         /**
+         * Removes all animation locks. Allows new animations to be added to any of the arcCamera properties.
+         */
+        FramingBehavior.prototype._clearAnimationLocks = function () {
+            this._betaIsAnimating = false;
+        };
+        /**
          *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
          */
         FramingBehavior.prototype._applyUserInteraction = function () {
             if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
                 this._lastInteractionTime = BABYLON.Tools.Now;
                 this.stopAllAnimations();
+                this._clearAnimationLocks();
             }
         };
         /**
@@ -69982,6 +70091,14 @@ var BABYLON;
                 this._attachedCamera.inertialPanningY !== 0 ||
                 this._isPointerDown;
         };
+        /**
+         * The easing function used by animations
+         */
+        FramingBehavior.EasingFunction = new BABYLON.ExponentialEase();
+        /**
+         * The easing mode used by animations
+         */
+        FramingBehavior.EasingMode = BABYLON.EasingFunction.EASINGMODE_EASEINOUT;
         // Statics
         /**
          * The camera can move all the way towards the model.
@@ -70006,14 +70123,6 @@ var BABYLON;
     var BouncingBehavior = (function () {
         function BouncingBehavior() {
             /**
-             * The easing function to use when the camera bounces
-             */
-            this.bounceEasingFunction = new BABYLON.BackEase(0.3);
-            /**
-             * The easing mode to use when the camera bounces
-             */
-            this.bounceEasingMode = BABYLON.EasingFunction.EASINGMODE_EASEOUT;
-            /**
              * The duration of the animation, in milliseconds
              */
             this.transitionDuration = 450;
@@ -70072,8 +70181,8 @@ var BABYLON;
         BouncingBehavior.prototype._applyBoundRadiusAnimation = function (radiusDelta) {
             var _this = this;
             if (!this._radiusBounceTransition) {
-                this.bounceEasingFunction.setEasingMode(this.bounceEasingMode);
-                this._radiusBounceTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, this.bounceEasingFunction);
+                BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);
+                this._radiusBounceTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);
             }
             // Prevent zoom until bounce has completed
             this._cachedWheelPrecision = this._attachedCamera.wheelPrecision;
@@ -70102,6 +70211,14 @@ var BABYLON;
                 this._animatables.shift();
             }
         };
+        /**
+         * The easing function used by animations
+         */
+        BouncingBehavior.EasingFunction = new BABYLON.BackEase(0.3);
+        /**
+         * The easing mode used by animations
+         */
+        BouncingBehavior.EasingMode = BABYLON.EasingFunction.EASINGMODE_EASEOUT;
         return BouncingBehavior;
     }());
     BABYLON.BouncingBehavior = BouncingBehavior;
@@ -70131,13 +70248,13 @@ var BABYLON;
         });
         Object.defineProperty(AutoRotationBehavior.prototype, "zoomStopsAnimation", {
             /**
-            * Gets the flag that indicates if user zooming should stop model animation.
+            * Gets the flag that indicates if user zooming should stop animation.
             */
             get: function () {
                 return this._zoomStopsAnimation;
             },
             /**
-            * Sets the flag that indicates if user zooming should stop model animation.
+            * Sets the flag that indicates if user zooming should stop animation.
             */
             set: function (flag) {
                 this._zoomStopsAnimation = flag;

Разница между файлами не показана из-за своего большого размера
+ 2773 - 2745
dist/preview release/babylon.module.d.ts


Разница между файлами не показана из-за своего большого размера
+ 38 - 38
dist/preview release/babylon.worker.js


Разница между файлами не показана из-за своего большого размера
+ 889 - 861
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Разница между файлами не показана из-за своего большого размера
+ 29 - 29
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 181 - 64
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -11634,6 +11634,18 @@ var BABYLON;
                 return false;
             return this.boundingBox.isInFrustum(frustumPlanes);
         };
+        Object.defineProperty(BoundingInfo.prototype, "diagonalLength", {
+            /**
+             * Gets the world distance between the min and max points of the bounding box
+             */
+            get: function () {
+                var boundingBox = this.boundingBox;
+                var size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
+                return size.length();
+            },
+            enumerable: true,
+            configurable: true
+        });
         BoundingInfo.prototype.isCompletelyInFrustum = function (frustumPlanes) {
             return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
         };
@@ -25026,7 +25038,12 @@ var BABYLON;
         };
         Material.prototype._afterBind = function (mesh) {
             this._scene._cachedMaterial = this;
-            this._scene._cachedVisibility = mesh.visibility;
+            if (mesh) {
+                this._scene._cachedVisibility = mesh.visibility;
+            }
+            else {
+                this._scene._cachedVisibility = 1;
+            }
             this.onBindObservable.notifyObservers(mesh);
             if (this.disableDepthWrite) {
                 var engine = this._scene.getEngine();
@@ -31669,6 +31686,7 @@ var BABYLON;
             _this._viewMatrix = new BABYLON.Matrix();
             // Panning
             _this.panningAxis = new BABYLON.Vector3(1, 1, 0);
+            _this.onMeshTargetChangedObservable = new BABYLON.Observable();
             _this.checkCollisions = false;
             _this.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5);
             _this._previousPosition = BABYLON.Vector3.Zero();
@@ -32109,6 +32127,7 @@ var BABYLON;
                 }
                 this._targetHost = target;
                 this._target = this._getTargetPosition();
+                this.onMeshTargetChangedObservable.notifyObservers(this._targetHost);
             }
             else {
                 var newTarget = target;
@@ -32118,6 +32137,7 @@ var BABYLON;
                 }
                 this._target = newTarget;
                 this._targetBoundingCenter = null;
+                this.onMeshTargetChangedObservable.notifyObservers(null);
             }
             this.rebuildAnglesAndRadius();
         };
@@ -49694,16 +49714,14 @@ var BABYLON;
     var FramingBehavior = (function () {
         function FramingBehavior() {
             this._mode = FramingBehavior.IgnoreBoundsSizeMode;
-            this._radius = 0;
-            this._elevation = 0;
+            this._radiusOffset = 0;
+            this._elevation = 0.3;
             this._positionY = 0;
-            this._defaultElevation = 0;
-            this._elevationReturnTime = 2;
-            this._elevationReturnWaitTime = 0;
+            this._defaultElevation = 0.3;
+            this._elevationReturnTime = 1500;
+            this._elevationReturnWaitTime = 1000;
             this._zoomStopsAnimation = false;
-            this._framingTime = 1.0;
-            this._easingFunction = new BABYLON.ExponentialEase();
-            this._easingMode = BABYLON.EasingFunction.EASINGMODE_EASEINOUT;
+            this._framingTime = 1500;
             this._isPointerDown = false;
             this._lastFrameTime = null;
             this._lastInteractionTime = -Infinity;
@@ -49719,38 +49737,6 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(FramingBehavior.prototype, "easingFunction", {
-            /**
-             * Gets the easing function to use for transitions
-             */
-            get: function () {
-                return this._easingFunction;
-            },
-            /**
-             * Sets the easing function to use for transitions
-             */
-            set: function (value) {
-                this._easingFunction = value;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(FramingBehavior.prototype, "easingMode", {
-            /**
-             * Gets the easing function to use for transitions
-             */
-            get: function () {
-                return this._easingMode;
-            },
-            /**
-             * Sets the easing function to use for transitions
-             */
-            set: function (value) {
-                this._easingMode = value;
-            },
-            enumerable: true,
-            configurable: true
-        });
         Object.defineProperty(FramingBehavior.prototype, "mode", {
             /**
              * Gets current mode used by the behavior.
@@ -49767,31 +49753,31 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(FramingBehavior.prototype, "radius", {
+        Object.defineProperty(FramingBehavior.prototype, "radiusOffset", {
             /**
-             * Gets the radius of the camera relative to the framed model's bounding box.
+             * Gets the radius of the camera relative to the target's bounding box.
              */
             get: function () {
-                return this._radius;
+                return this._radiusOffset;
             },
             /**
-             * Sets the radius of the camera relative to the framed model's bounding box.
+             * Sets the radius of the camera relative to the target's bounding box.
              */
             set: function (radius) {
-                this._radius = radius;
+                this._radiusOffset = radius;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(FramingBehavior.prototype, "elevation", {
             /**
-             * Gets the elevation of the camera from the framed model, in radians.
+             * Gets the elevation of the camera from the target, in radians.
              */
             get: function () {
                 return this._elevation;
             },
             /**
-             * Sets the elevation of the camera from the framed model, in radians.
+             * Sets the elevation of the camera from the target, in radians.
              */
             set: function (elevation) {
                 this._elevation = elevation;
@@ -49912,6 +49898,11 @@ var BABYLON;
                     _this._isPointerDown = false;
                 }
             });
+            this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add(function (mesh) {
+                if (mesh) {
+                    _this.zoomOnMesh(mesh);
+                }
+            });
             this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(function () {
                 // Stop the animation if there is user interaction and the animation should stop for this interaction
                 _this._applyUserInteraction();
@@ -49924,6 +49915,97 @@ var BABYLON;
             var scene = this._attachedCamera.getScene();
             scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
             camera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+            camera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
+        };
+        /**
+         * Targets the given mesh and updates zoom level accordingly.
+         * @param mesh  The mesh to target.
+         * @param radius Optional. If a cached radius position already exists, overrides default.
+         * @param applyToLowerLimit Optional. Indicates if the calculated target radius should be applied to the
+         *		camera's lower radius limit too.
+         * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
+         * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
+         */
+        FramingBehavior.prototype.zoomOnMesh = function (mesh, radius, applyToLowerLimit, framingPositionY, focusOnOriginXZ) {
+            if (applyToLowerLimit === void 0) { applyToLowerLimit = false; }
+            if (focusOnOriginXZ === void 0) { focusOnOriginXZ = true; }
+            if (framingPositionY == null) {
+                framingPositionY = this._positionY;
+            }
+            // sets the radius and lower radius bounds
+            if (radius == null) {
+                // Small delta ensures camera is not always at lower zoom limit.
+                var delta = 0.1;
+                if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+                    var position = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+                    this._attachedCamera.lowerRadiusLimit = position - delta;
+                    radius = position;
+                }
+                else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                    radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+                }
+            }
+            var zoomTarget;
+            var zoomTargetY;
+            mesh.computeWorldMatrix(true);
+            var modelWorldPosition = new BABYLON.Vector3(0, 0, 0);
+            var modelWorldScale = new BABYLON.Vector3(0, 0, 0);
+            mesh.getWorldMatrix().decompose(modelWorldScale, new BABYLON.Quaternion(), modelWorldPosition);
+            //find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+            var bottom = modelWorldPosition.y + mesh.getBoundingInfo().minimum.y;
+            var top = modelWorldPosition.y + mesh.getBoundingInfo().maximum.y;
+            zoomTargetY = bottom + (top - bottom) * framingPositionY;
+            if (applyToLowerLimit) {
+                this._attachedCamera.lowerRadiusLimit = radius;
+            }
+            if (!this._radiusTransition) {
+                FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+                this._radiusTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
+            }
+            // transition to new radius
+            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime));
+            if (focusOnOriginXZ) {
+                zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
+            }
+            else {
+                zoomTarget = new BABYLON.Vector3(modelWorldPosition.x, zoomTargetY, modelWorldPosition.z);
+            }
+            // if (!this._vectorTransition) {
+            // 	FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+            // 	this._vectorTransition = Animation.CreateAnimation("target", Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
+            // }			
+            // this._animatables.push(Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 
+            // 						60, this._vectorTransition, this._framingTime));
+        };
+        /**
+         * Calculates the lowest radius for the camera based on the bounding box of the mesh.
+         * @param mesh The mesh on which to base the calculation. mesh boundingInfo used to estimate necessary
+         *			  frustum width.
+         * @param framingRadius An additional factor to add to the return camera radius.
+         * @return The minimum distance from the primary mesh's center point at which the camera must be kept in order
+         *		 to fully enclose the mesh in the viewing frustum.
+         */
+        FramingBehavior.prototype._calculateLowerRadiusFromModelBoundingSphere = function (mesh, framingRadius) {
+            var boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+            var frustumSlope = this._getFrustumSlope();
+            // Formula for setting distance
+            // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)
+            var radiusWithoutFraming = boxVectorGlobalDiagonal * 0.5;
+            // Horizon distance
+            var radius = radiusWithoutFraming * framingRadius;
+            var distanceForHorizontalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.x * frustumSlope.x));
+            var distanceForVerticalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.y * frustumSlope.y));
+            var distance = Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);
+            var camera = this._attachedCamera;
+            if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                // Don't exceed the requested limit
+                distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;
+            }
+            // Don't exceed the upper radius limit
+            if (camera.upperRadiusLimit) {
+                distance = distance > camera.upperRadiusLimit ? camera.upperRadiusLimit : distance;
+            }
+            return distance;
         };
         /**
          * Keeps the camera above the ground plane. If the user pulls the camera below the ground plane, the camera
@@ -49940,15 +50022,35 @@ var BABYLON;
                 //Transition to new position
                 this.stopAllAnimations();
                 if (!this._betaTransition) {
-                    this.easingFunction.setEasingMode(this.easingMode);
-                    this._betaTransition = BABYLON.Animation.CreateAnimation("beta", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, this.easingFunction);
+                    FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+                    this._betaTransition = BABYLON.Animation.CreateAnimation("beta", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
                 }
-                BABYLON.Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._betaTransition, this._elevationReturnTime, function () {
+                this._animatables.push(BABYLON.Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._betaTransition, this._elevationReturnTime, function () {
+                    _this._clearAnimationLocks();
                     _this.stopAllAnimations();
-                });
+                }));
             }
         };
         /**
+         * Returns the frustum slope based on the canvas ratio and camera FOV
+         * @returns The frustum slope represented as a Vector2 with X and Y slopes
+         */
+        FramingBehavior.prototype._getFrustumSlope = function () {
+            // Calculate the viewport ratio
+            // Aspect Ratio is Height/Width.
+            var camera = this._attachedCamera;
+            var engine = camera.getScene().getEngine();
+            var aspectRatio = engine.getAspectRatio(camera);
+            // Camera FOV is the vertical field of view (top-bottom) in radians.
+            // Slope of the frustum top/bottom planes in view space, relative to the forward vector.
+            var frustumSlopeY = Math.tan(camera.fov / 2);
+            // Slope of the frustum left/right planes in view space, relative to the forward vector.
+            // Provides the amount that one side (e.g. left) of the frustum gets wider for every unit
+            // along the forward vector.
+            var frustumSlopeX = frustumSlopeY / aspectRatio;
+            return new BABYLON.Vector2(frustumSlopeX, frustumSlopeY);
+        };
+        /**
          * Returns true if user is scrolling.
          * @return true if user is scrolling.
          */
@@ -49970,12 +50072,19 @@ var BABYLON;
             return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
         };
         /**
+         * Removes all animation locks. Allows new animations to be added to any of the arcCamera properties.
+         */
+        FramingBehavior.prototype._clearAnimationLocks = function () {
+            this._betaIsAnimating = false;
+        };
+        /**
          *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
          */
         FramingBehavior.prototype._applyUserInteraction = function () {
             if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
                 this._lastInteractionTime = BABYLON.Tools.Now;
                 this.stopAllAnimations();
+                this._clearAnimationLocks();
             }
         };
         /**
@@ -49998,6 +50107,14 @@ var BABYLON;
                 this._attachedCamera.inertialPanningY !== 0 ||
                 this._isPointerDown;
         };
+        /**
+         * The easing function used by animations
+         */
+        FramingBehavior.EasingFunction = new BABYLON.ExponentialEase();
+        /**
+         * The easing mode used by animations
+         */
+        FramingBehavior.EasingMode = BABYLON.EasingFunction.EASINGMODE_EASEINOUT;
         // Statics
         /**
          * The camera can move all the way towards the model.
@@ -50022,14 +50139,6 @@ var BABYLON;
     var BouncingBehavior = (function () {
         function BouncingBehavior() {
             /**
-             * The easing function to use when the camera bounces
-             */
-            this.bounceEasingFunction = new BABYLON.BackEase(0.3);
-            /**
-             * The easing mode to use when the camera bounces
-             */
-            this.bounceEasingMode = BABYLON.EasingFunction.EASINGMODE_EASEOUT;
-            /**
              * The duration of the animation, in milliseconds
              */
             this.transitionDuration = 450;
@@ -50088,8 +50197,8 @@ var BABYLON;
         BouncingBehavior.prototype._applyBoundRadiusAnimation = function (radiusDelta) {
             var _this = this;
             if (!this._radiusBounceTransition) {
-                this.bounceEasingFunction.setEasingMode(this.bounceEasingMode);
-                this._radiusBounceTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, this.bounceEasingFunction);
+                BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);
+                this._radiusBounceTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);
             }
             // Prevent zoom until bounce has completed
             this._cachedWheelPrecision = this._attachedCamera.wheelPrecision;
@@ -50118,6 +50227,14 @@ var BABYLON;
                 this._animatables.shift();
             }
         };
+        /**
+         * The easing function used by animations
+         */
+        BouncingBehavior.EasingFunction = new BABYLON.BackEase(0.3);
+        /**
+         * The easing mode used by animations
+         */
+        BouncingBehavior.EasingMode = BABYLON.EasingFunction.EASINGMODE_EASEOUT;
         return BouncingBehavior;
     }());
     BABYLON.BouncingBehavior = BouncingBehavior;
@@ -50147,13 +50264,13 @@ var BABYLON;
         });
         Object.defineProperty(AutoRotationBehavior.prototype, "zoomStopsAnimation", {
             /**
-            * Gets the flag that indicates if user zooming should stop model animation.
+            * Gets the flag that indicates if user zooming should stop animation.
             */
             get: function () {
                 return this._zoomStopsAnimation;
             },
             /**
-            * Sets the flag that indicates if user zooming should stop model animation.
+            * Sets the flag that indicates if user zooming should stop animation.
             */
             set: function (flag) {
                 this._zoomStopsAnimation = flag;

Разница между файлами не показана из-за своего большого размера
+ 889 - 861
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


Разница между файлами не показана из-за своего большого размера
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


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

@@ -299,10 +299,7 @@ declare module INSPECTOR {
 }
 
 declare module INSPECTOR {
-    interface IHighlight {
-        highlight: (b: boolean) => void;
-    }
-    abstract class Adapter implements IHighlight {
+    abstract class Adapter {
         protected _obj: any;
         private static _name;
         constructor(obj: any);
@@ -324,8 +321,6 @@ declare module INSPECTOR {
         readonly object: any;
         /** Returns the list of tools available for this adapter */
         abstract getTools(): Array<AbstractTreeTool>;
-        /** Should be overriden in subclasses */
-        highlight(b: boolean): void;
     }
 }
 
@@ -415,9 +410,6 @@ declare module INSPECTOR {
         getTools(): Array<AbstractTreeTool>;
         setVisible(b: boolean): void;
         isVisible(): boolean;
-        /** Returns some information about this mesh */
-        /** Overrides super.highlight */
-        highlight(b: boolean): void;
     }
 }
 
@@ -432,10 +424,6 @@ declare module INSPECTOR {
         getProperties(): Array<PropertyLine>;
         /** No tools for a material adapter */
         getTools(): Array<AbstractTreeTool>;
-        /** Overrides super.highlight.
-         * Highlighting a material outlines all meshes linked to this material
-         */
-        highlight(b: boolean): void;
     }
 }
 
@@ -458,8 +446,6 @@ declare module INSPECTOR {
         debug(b: boolean): void;
         /** Returns some information about this mesh */
         getInfo(): string;
-        /** Overrides super.highlight */
-        highlight(b: boolean): void;
         /** Draw X, Y and Z axis for the actual object if this adapter.
          * Should be called only one time as it will fill this._axis
          */
@@ -803,8 +789,6 @@ declare module INSPECTOR {
         abstract dispose(): any;
         /** Select an item in the tree */
         select(item: TreeItem): void;
-        /** Highlight the given node, and downplay all others */
-        highlightNode(item?: TreeItem): void;
         /**
          * Returns the total width in pixel of this tab, 0 by default
         */
@@ -835,8 +819,6 @@ declare module INSPECTOR {
         displayDetails(item: TreeItem): void;
         /** Select an item in the tree */
         select(item: TreeItem): void;
-        /** Highlight the given node, and downplay all others */
-        highlightNode(item?: TreeItem): void;
         /** Set the given item as active in the tree */
         activateNode(item: TreeItem): void;
         /** Returns the treeitem corersponding to the given obj, null if not found */
@@ -893,8 +875,6 @@ declare module INSPECTOR {
         select(item: TreeItem): void;
         /** Set the given item as active in the tree */
         activateNode(item: TreeItem): void;
-        /** Highlight the given node, and downplay all others */
-        highlightNode(item?: TreeItem): void;
     }
 }
 
@@ -1189,11 +1169,8 @@ declare module INSPECTOR {
         /**
          * Add an event listener on the item :
          * - one click display details
-         * - on mouse hover the item is highlighted
          */
         protected _addEvent(): void;
-        /** Highlight or downplay this node */
-        highlight(b: boolean): void;
         /** Returns true if the node is folded, false otherwise */
         private _isFolded();
         /** Set this item as active (background lighter) in the tree panel */

+ 0 - 86
dist/preview release/inspector/babylon.inspector.js

@@ -924,9 +924,6 @@ var INSPECTOR;
             enumerable: true,
             configurable: true
         });
-        /** Should be overriden in subclasses */
-        Adapter.prototype.highlight = function (b) { };
-        ;
         // a unique name for this adapter, to retrieve its own key in the local storage
         Adapter._name = BABYLON.Geometry.RandomId();
         return Adapter;
@@ -1368,16 +1365,6 @@ var INSPECTOR;
         LightAdapter.prototype.isVisible = function () {
             return this._obj.isEnabled();
         };
-        /** Returns some information about this mesh */
-        // public getInfo() : string {
-        //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
-        // }
-        /** Overrides super.highlight */
-        LightAdapter.prototype.highlight = function (b) {
-            this.actualObject.renderOutline = b;
-            this.actualObject.outlineWidth = 0.25;
-            this.actualObject.outlineColor = BABYLON.Color3.Yellow();
-        };
         LightAdapter._PROPERTIES = [
             'position',
             'diffuse',
@@ -1444,19 +1431,6 @@ var INSPECTOR;
         MaterialAdapter.prototype.getTools = function () {
             return [];
         };
-        /** Overrides super.highlight.
-         * Highlighting a material outlines all meshes linked to this material
-         */
-        MaterialAdapter.prototype.highlight = function (b) {
-            var material = this.actualObject;
-            var meshes = material.getBindedMeshes();
-            for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
-                var mesh = meshes_1[_i];
-                mesh.renderOutline = b;
-                mesh.outlineWidth = 0.25;
-                mesh.outlineColor = BABYLON.Color3.Yellow();
-            }
-        };
         return MaterialAdapter;
     }(INSPECTOR.Adapter));
     INSPECTOR.MaterialAdapter = MaterialAdapter;
@@ -1544,12 +1518,6 @@ var INSPECTOR;
         MeshAdapter.prototype.getInfo = function () {
             return this._obj.getTotalVertices() + " vertices";
         };
-        /** Overrides super.highlight */
-        MeshAdapter.prototype.highlight = function (b) {
-            this.actualObject.renderOutline = b;
-            this.actualObject.outlineWidth = 0.25;
-            this.actualObject.outlineColor = BABYLON.Color3.Yellow();
-        };
         /** Draw X, Y and Z axis for the actual object if this adapter.
          * Should be called only one time as it will fill this._axis
          */
@@ -2734,10 +2702,6 @@ var INSPECTOR;
         Tab.prototype.select = function (item) {
             // To define in subclasses if needed 
         };
-        /** Highlight the given node, and downplay all others */
-        Tab.prototype.highlightNode = function (item) {
-            // To define in subclasses if needed
-        };
         /**
          * Returns the total width in pixel of this tab, 0 by default
         */
@@ -2832,25 +2796,11 @@ var INSPECTOR;
         };
         /** Select an item in the tree */
         PropertyTab.prototype.select = function (item) {
-            // Remove the node highlight
-            this.highlightNode();
             // Active the node
             this.activateNode(item);
             // Display its details
             this.displayDetails(item);
         };
-        /** Highlight the given node, and downplay all others */
-        PropertyTab.prototype.highlightNode = function (item) {
-            if (this._treeItems) {
-                for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
-                    var node = _a[_i];
-                    node.highlight(false);
-                }
-            }
-            if (item) {
-                item.highlight(true);
-            }
-        };
         /** Set the given item as active in the tree */
         PropertyTab.prototype.activateNode = function (item) {
             if (this._treeItems) {
@@ -3208,8 +3158,6 @@ var INSPECTOR;
         };
         /** Select an item in the tree */
         TextureTab.prototype.select = function (item) {
-            // Remove the node highlight
-            this.highlightNode();
             // Active the node
             this.activateNode(item);
             // Display its details
@@ -3225,18 +3173,6 @@ var INSPECTOR;
             }
             item.active(true);
         };
-        /** Highlight the given node, and downplay all others */
-        TextureTab.prototype.highlightNode = function (item) {
-            if (this._treeItems) {
-                for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
-                    var node = _a[_i];
-                    node.highlight(false);
-                }
-            }
-            if (item) {
-                item.highlight(true);
-            }
-        };
         return TextureTab;
     }(INSPECTOR.Tab));
     INSPECTOR.TextureTab = TextureTab;
@@ -4846,7 +4782,6 @@ var INSPECTOR;
         /**
          * Add an event listener on the item :
          * - one click display details
-         * - on mouse hover the item is highlighted
          */
         TreeItem.prototype._addEvent = function () {
             var _this = this;
@@ -4861,27 +4796,6 @@ var INSPECTOR;
                 }
                 e.stopPropagation();
             });
-            // Highlight on mouse over
-            this._div.addEventListener('mouseover', function (e) {
-                _this._tab.highlightNode(_this);
-                e.stopPropagation();
-            });
-            // Remove highlight on mouse out
-            this._div.addEventListener('mouseout', function (e) {
-                _this._tab.highlightNode();
-            });
-        };
-        /** Highlight or downplay this node */
-        TreeItem.prototype.highlight = function (b) {
-            // Remove highlight for all children 
-            if (!b) {
-                for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
-                    var child = _a[_i];
-                    child._adapter.highlight(b);
-                }
-            }
-            // Highlight this node
-            this._adapter.highlight(b);
         };
         /** Returns true if the node is folded, false otherwise */
         TreeItem.prototype._isFolded = function () {

Разница между файлами не показана из-за своего большого размера
+ 4 - 4
dist/preview release/inspector/babylon.inspector.min.js


+ 1 - 8
inspector/src/adapters/Adapter.ts

@@ -1,10 +1,6 @@
 module INSPECTOR {
 
-    export interface IHighlight {
-        highlight: (b: boolean) => void
-    }
-
-    export abstract class Adapter implements IHighlight {
+    export abstract class Adapter {
 
         protected _obj: any;
         // a unique name for this adapter, to retrieve its own key in the local storage
@@ -48,8 +44,5 @@ module INSPECTOR {
 
         /** Returns the list of tools available for this adapter */
         public abstract getTools(): Array<AbstractTreeTool>;
-
-        /** Should be overriden in subclasses */
-        public highlight(b: boolean) { };
     }
 }

+ 0 - 7
inspector/src/adapters/LightAdapter.ts

@@ -59,12 +59,5 @@ module INSPECTOR {
         // public getInfo() : string {
         //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
         // }
-        
-        /** Overrides super.highlight */
-        public highlight(b:boolean) {
-            this.actualObject.renderOutline = b;
-			this.actualObject.outlineWidth = 0.25;
-			this.actualObject.outlineColor = BABYLON.Color3.Yellow();
-        }
     }
 }

+ 0 - 13
inspector/src/adapters/MaterialAdapter.ts

@@ -43,18 +43,5 @@ module INSPECTOR {
         public getTools() : Array<AbstractTreeTool> {
             return [];
         }
-
-        /** Overrides super.highlight.
-         * Highlighting a material outlines all meshes linked to this material
-         */
-        public highlight(b:boolean) {
-            let material = this.actualObject as BABYLON.Material;
-            let meshes = material.getBindedMeshes();
-            for (let mesh of meshes) {
-                mesh.renderOutline = b;
-                mesh.outlineWidth = 0.25;
-                mesh.outlineColor = BABYLON.Color3.Yellow();
-            }
-        }
     }
 }

+ 0 - 6
inspector/src/adapters/MeshAdapter.ts

@@ -78,12 +78,6 @@ module INSPECTOR {
             return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
         }
 
-        /** Overrides super.highlight */
-        public highlight(b: boolean) {
-            this.actualObject.renderOutline = b;
-            this.actualObject.outlineWidth = 0.25;
-            this.actualObject.outlineColor = BABYLON.Color3.Yellow();
-        }
         /** Draw X, Y and Z axis for the actual object if this adapter.
          * Should be called only one time as it will fill this._axis
          */

+ 0 - 15
inspector/src/tabs/PropertyTab.ts

@@ -87,26 +87,11 @@ module INSPECTOR{
         
         /** Select an item in the tree */
         public select(item:TreeItem) {            
-            // Remove the node highlight
-            this.highlightNode();
             // Active the node
             this.activateNode(item);
             // Display its details
             this.displayDetails(item); 
         }
-        
-
-        /** Highlight the given node, and downplay all others */
-         public highlightNode(item?:TreeItem) {
-            if (this._treeItems) {
-                for (let node of this._treeItems) {
-                    node.highlight(false);
-                }
-            }
-            if (item) {
-                item.highlight(true);
-            }
-        }
 
         /** Set the given item as active in the tree */
         public activateNode(item:TreeItem) {

+ 0 - 6
inspector/src/tabs/Tab.ts

@@ -61,12 +61,6 @@ module INSPECTOR {
             // To define in subclasses if needed 
         }
 
-
-        /** Highlight the given node, and downplay all others */
-        public highlightNode(item?: TreeItem) {
-            // To define in subclasses if needed
-        }
-
         /** 
          * Returns the total width in pixel of this tab, 0 by default
         */

+ 0 - 15
inspector/src/tabs/TextureTab.ts

@@ -141,8 +141,6 @@ module INSPECTOR {
 
         /** Select an item in the tree */
         public select(item: TreeItem) {
-            // Remove the node highlight
-            this.highlightNode();
             // Active the node
             this.activateNode(item);
             // Display its details
@@ -158,19 +156,6 @@ module INSPECTOR {
             }
             item.active(true);
         }
-
-        /** Highlight the given node, and downplay all others */
-        public highlightNode(item?: TreeItem) {
-            if (this._treeItems) {
-                for (let node of this._treeItems) {
-                    node.highlight(false);
-                }
-            }
-            if (item) {
-                item.highlight(true);
-            }
-        }
-
     }
 
 }

+ 0 - 23
inspector/src/tree/TreeItem.ts

@@ -133,7 +133,6 @@ module INSPECTOR {
         /**
          * Add an event listener on the item : 
          * - one click display details
-         * - on mouse hover the item is highlighted
          */
         protected _addEvent() {
             this._div.addEventListener('click', (e) => {
@@ -146,28 +145,6 @@ module INSPECTOR {
                 }
                 e.stopPropagation();
             });
-
-            // Highlight on mouse over
-            this._div.addEventListener('mouseover', (e) => {
-                this._tab.highlightNode(this);
-                e.stopPropagation();
-            });
-            // Remove highlight on mouse out
-            this._div.addEventListener('mouseout', (e) => {
-                this._tab.highlightNode();
-            });
-        }
-
-        /** Highlight or downplay this node */
-        public highlight(b: boolean) {
-            // Remove highlight for all children 
-            if (!b) {
-                for (let child of this.children) {
-                    child._adapter.highlight(b);
-                }
-            }
-            // Highlight this node
-            this._adapter.highlight(b);
         }
 
         /** Returns true if the node is folded, false otherwise */

+ 2 - 2
src/Behaviors/Cameras/babylon.autoRotationBehavior.ts

@@ -10,14 +10,14 @@ module BABYLON {
         private _idleRotationSpinupTime = 2000;  
        
 		/**
-		* Sets the flag that indicates if user zooming should stop model animation.
+		* Sets the flag that indicates if user zooming should stop animation.
 		*/
 		public set zoomStopsAnimation(flag: boolean) {
 			this._zoomStopsAnimation = flag;
 		}
 
 		/**
-		* Gets the flag that indicates if user zooming should stop model animation.
+		* Gets the flag that indicates if user zooming should stop animation.
 		*/
 		public get zoomStopsAnimation(): boolean {
 			return this._zoomStopsAnimation;

+ 6 - 6
src/Behaviors/Cameras/babylon.bouncingBehavior.ts

@@ -8,14 +8,14 @@ module BABYLON {
         }        
 
 		/**
-		 * The easing function to use when the camera bounces
+		 * The easing function used by animations
 		 */
-		public bounceEasingFunction = new BackEase(0.3);
+		public static EasingFunction = new BackEase(0.3);
 
 		/**
-		 * The easing mode to use when the camera bounces
+		 * The easing mode used by animations
 		 */
-        public bounceEasingMode = EasingFunction.EASINGMODE_EASEOUT;   
+        public static EasingMode = EasingFunction.EASINGMODE_EASEOUT;   
         
         /**
          * The duration of the animation, in milliseconds
@@ -79,8 +79,8 @@ module BABYLON {
 		 */
 		private _applyBoundRadiusAnimation(radiusDelta: number): void {
 			if (!this._radiusBounceTransition) {
-				this.bounceEasingFunction.setEasingMode(this.bounceEasingMode);
-				this._radiusBounceTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, this.bounceEasingFunction);
+				BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);
+				this._radiusBounceTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);
 			}
             // Prevent zoom until bounce has completed
             this._cachedWheelPrecision = this._attachedCamera.wheelPrecision;

+ 178 - 51
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -5,44 +5,24 @@ module BABYLON {
         }
 
         private _mode = FramingBehavior.IgnoreBoundsSizeMode;
-        private _radius = 0;
-        private _elevation = 0;
+        private _radiusOffset = 0;
+        private _elevation = 0.3;
         private _positionY = 0;
-        private _defaultElevation = 0;
-        private _elevationReturnTime = 2;
-        private _elevationReturnWaitTime = 0;
+        private _defaultElevation = 0.3;
+        private _elevationReturnTime = 1500;
+        private _elevationReturnWaitTime = 1000;
         private _zoomStopsAnimation = false;
-		private _framingTime = 1.0;
-        private _easingFunction: EasingFunction = new ExponentialEase();
-        private _easingMode = EasingFunction.EASINGMODE_EASEINOUT;
-        
+		private _framingTime = 1500;
+		
 		/**
-		 * Gets the easing function to use for transitions
-		 */
-		public get easingFunction(): EasingFunction {
-            return this._easingFunction;
-        }
-        
-        /**
-		 * Sets the easing function to use for transitions
+		 * The easing function used by animations
 		 */
-		public set easingFunction(value: EasingFunction) {
-            this._easingFunction = value;
-        }    
-
+		public static EasingFunction = new ExponentialEase();
+		
 		/**
-		 * Gets the easing function to use for transitions
+		 * The easing mode used by animations
 		 */
-		public get easingMode(): number {
-            return this._easingMode;
-        }
-        
-        /**
-		 * Sets the easing function to use for transitions
-		 */
-		public set easingMode(value: number) {
-            this._easingMode = value;
-        }          
+		public static EasingMode = EasingFunction.EASINGMODE_EASEINOUT;   		
 
         /**
 		 * Sets the current mode used by the behavior
@@ -59,28 +39,28 @@ module BABYLON {
         }
         
 	    /**
-		 * Sets the radius of the camera relative to the framed model's bounding box.
+		 * Sets the radius of the camera relative to the target's bounding box.
 		 */
-		public set radius(radius: number) {
-			this._radius = radius;
+		public set radiusOffset(radius: number) {
+			this._radiusOffset = radius;
 		}
 
 		/**
-		 * Gets the radius of the camera relative to the framed model's bounding box.
+		 * Gets the radius of the camera relative to the target's bounding box.
 		 */
-		public get radius(): number {
-			return this._radius;
+		public get radiusOffset(): number {
+			return this._radiusOffset;
 		}
 
 		/**
-		 * Sets the elevation of the camera from the framed model, in radians.
+		 * Sets the elevation of the camera from the target, in radians.
 		 */
 		public set elevation(elevation: number) {
 			this._elevation = elevation;
 		}
 
 		/**
-		 * Gets the elevation of the camera from the framed model, in radians.
+		 * Gets the elevation of the camera from the target, in radians.
 		 */
 		public get elevation(): number {
 			return this._elevation;
@@ -176,7 +156,8 @@ module BABYLON {
         
         // Default behavior functions
         private _onPrePointerObservableObserver: Observer<PointerInfoPre>;
-        private _onAfterCheckInputsObserver: Observer<Camera>;
+		private _onAfterCheckInputsObserver: Observer<Camera>;
+		private _onMeshTargetChangedObserver: Observer<AbstractMesh>;
         private _attachedCamera: ArcRotateCamera;
         private _isPointerDown = false;
         private _lastFrameTime: number = null;
@@ -195,7 +176,13 @@ module BABYLON {
                 if (pointerInfoPre.type === PointerEventTypes.POINTERUP) {
                     this._isPointerDown = false;
                 }
-            });
+			});
+			
+			this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add((mesh) => {
+				if (mesh) {
+					this.zoomOnMesh(mesh);
+				}
+			});
 
             this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {      
                 // Stop the animation if there is user interaction and the animation should stop for this interaction
@@ -211,14 +198,122 @@ module BABYLON {
             let scene = this._attachedCamera.getScene();
             
             scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
-            camera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+			camera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+			camera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
         }
 
         // Framing control
-        private _animatables = new Array<BABYLON.Animatable>();
+        private _animatables = new Array<Animatable>();
         private _betaIsAnimating = false;
-        private _betaTransition: BABYLON.Animation;
-        private _lastFrameRadius = 0;
+		private _betaTransition: Animation;
+		private _radiusTransition: Animation;
+		private _vectorTransition: Animation;
+		private _lastFrameRadius = 0;
+		
+		/**
+		 * Targets the given mesh and updates zoom level accordingly.
+		 * @param mesh  The mesh to target.
+		 * @param radius Optional. If a cached radius position already exists, overrides default.
+		 * @param applyToLowerLimit Optional. Indicates if the calculated target radius should be applied to the
+		 *		camera's lower radius limit too.
+		 * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
+		 * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
+		 */
+		public zoomOnMesh(mesh: AbstractMesh, radius?: number, applyToLowerLimit: boolean = false, framingPositionY?: number, focusOnOriginXZ: boolean = true): void {
+			if (framingPositionY == null) {
+				framingPositionY = this._positionY;
+			}
+
+			// sets the radius and lower radius bounds
+			if (radius == null) {
+				// Small delta ensures camera is not always at lower zoom limit.
+				let delta = 0.1;
+				if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+					let position = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+					this._attachedCamera.lowerRadiusLimit = position - delta;
+					radius = position;
+				} else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+					radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh, this.radiusOffset);
+				}
+			}
+
+			let zoomTarget: BABYLON.Vector3;
+			let zoomTargetY: number;
+
+			mesh.computeWorldMatrix(true);
+			let modelWorldPosition = new BABYLON.Vector3(0, 0, 0);
+			let modelWorldScale = new BABYLON.Vector3(0, 0, 0);
+
+			mesh.getWorldMatrix().decompose(modelWorldScale, new BABYLON.Quaternion(), modelWorldPosition);
+
+			//find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+			let bottom = modelWorldPosition.y + mesh.getBoundingInfo().minimum.y;
+			let top = modelWorldPosition.y + mesh.getBoundingInfo().maximum.y;
+			zoomTargetY = bottom + (top - bottom) * framingPositionY;
+
+			if (applyToLowerLimit) {
+				this._attachedCamera.lowerRadiusLimit = radius;
+			}
+
+			if (!this._radiusTransition) {
+				FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+				this._radiusTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
+			}
+
+			// transition to new radius
+			this._animatables.push(Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 
+									60, this._radiusTransition, this._framingTime));
+
+			if (focusOnOriginXZ) {	
+				zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
+			} else {
+				zoomTarget = new BABYLON.Vector3(modelWorldPosition.x, zoomTargetY, modelWorldPosition.z);
+			}
+
+			// if (!this._vectorTransition) {
+			// 	FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+			// 	this._vectorTransition = Animation.CreateAnimation("target", Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
+			// }			
+
+			// this._animatables.push(Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 
+			// 						60, this._vectorTransition, this._framingTime));
+		}	
+		
+		/**
+		 * Calculates the lowest radius for the camera based on the bounding box of the mesh.
+		 * @param mesh The mesh on which to base the calculation. mesh boundingInfo used to estimate necessary
+		 *			  frustum width.
+		 * @param framingRadius An additional factor to add to the return camera radius.
+		 * @return The minimum distance from the primary mesh's center point at which the camera must be kept in order
+		 *		 to fully enclose the mesh in the viewing frustum.
+		 */
+		protected _calculateLowerRadiusFromModelBoundingSphere(mesh: AbstractMesh, framingRadius: number): number {
+            let boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+			let frustumSlope: BABYLON.Vector2 = this._getFrustumSlope();
+
+			// Formula for setting distance
+			// (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)
+			let radiusWithoutFraming = boxVectorGlobalDiagonal * 0.5;
+
+			// Horizon distance
+			let radius = radiusWithoutFraming * framingRadius;
+			let distanceForHorizontalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.x * frustumSlope.x));
+			let distanceForVerticalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.y * frustumSlope.y));
+			let distance = Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);
+			let camera = this._attachedCamera;
+
+			if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+				// Don't exceed the requested limit
+				distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;
+			}
+
+			// Don't exceed the upper radius limit
+			if (camera.upperRadiusLimit) {
+				distance = distance > camera.upperRadiusLimit ? camera.upperRadiusLimit : distance;
+			}
+
+			return distance;
+		}		
 
 		/**
 		 * Keeps the camera above the ground plane. If the user pulls the camera below the ground plane, the camera
@@ -237,19 +332,43 @@ module BABYLON {
                 this.stopAllAnimations();
                 
                 if (!this._betaTransition) {
-                    this.easingFunction.setEasingMode(this.easingMode);
-                    this._betaTransition = Animation.CreateAnimation("beta", Animation.ANIMATIONTYPE_FLOAT, 60, this.easingFunction);
+                    FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
+                    this._betaTransition = Animation.CreateAnimation("beta", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
                 }
 
-				Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60,
+				this._animatables.push(Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60,
                     this._betaTransition, this._elevationReturnTime, 
                     () => {
+						this._clearAnimationLocks();
 						this.stopAllAnimations();
-					});
+					}));
 			}
 		}        
 
 		/**
+		 * Returns the frustum slope based on the canvas ratio and camera FOV
+		 * @returns The frustum slope represented as a Vector2 with X and Y slopes
+		 */
+		private _getFrustumSlope(): Vector2 {
+			// Calculate the viewport ratio
+			// Aspect Ratio is Height/Width.
+			let camera = this._attachedCamera;
+			let engine = camera.getScene().getEngine();
+			var aspectRatio = engine.getAspectRatio(camera);
+
+			// Camera FOV is the vertical field of view (top-bottom) in radians.
+			// Slope of the frustum top/bottom planes in view space, relative to the forward vector.
+			var frustumSlopeY = Math.tan(camera.fov / 2);
+
+			// Slope of the frustum left/right planes in view space, relative to the forward vector.
+			// Provides the amount that one side (e.g. left) of the frustum gets wider for every unit
+			// along the forward vector.
+			var frustumSlopeX = frustumSlopeY / aspectRatio;
+
+			return new Vector2(frustumSlopeX, frustumSlopeY);
+		}		
+
+		/**
 		 * Returns true if user is scrolling. 
 		 * @return true if user is scrolling.
 		 */
@@ -274,12 +393,20 @@ module BABYLON {
 		}        
 
 		/**
+		 * Removes all animation locks. Allows new animations to be added to any of the arcCamera properties.
+		 */
+		private _clearAnimationLocks(): void {
+			this._betaIsAnimating = false;
+		}		
+
+		/**
 		 *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
 		 */          
         private _applyUserInteraction(): void {
 			if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
                 this._lastInteractionTime = Tools.Now;
-				this.stopAllAnimations();
+				this.stopAllAnimations();				
+				this._clearAnimationLocks();
 			}
         }                
         

+ 5 - 1
src/Cameras/babylon.arcRotateCamera.ts

@@ -251,8 +251,9 @@ module BABYLON {
                 this._autoRotationBehavior = null;
             }
         }        
-        
 
+        public onMeshTargetChangedObservable = new Observable<AbstractMesh>();
+        
         // Collisions
         public onCollide: (collidedMesh: AbstractMesh) => void;
         public checkCollisions = false;
@@ -502,6 +503,8 @@ module BABYLON {
                 }
                 this._targetHost = <AbstractMesh>target;
                 this._target = this._getTargetPosition();
+
+                this.onMeshTargetChangedObservable.notifyObservers(this._targetHost);
             } else {
                 var newTarget = <Vector3>target;
                 var currentTarget = this._getTargetPosition();
@@ -510,6 +513,7 @@ module BABYLON {
                 }
                 this._target = newTarget;
                 this._targetBoundingCenter = null;
+                this.onMeshTargetChangedObservable.notifyObservers(null);
             }
 
             this.rebuildAnglesAndRadius();

+ 9 - 0
src/Culling/babylon.boundingInfo.ts

@@ -62,6 +62,15 @@
             return this.boundingBox.isInFrustum(frustumPlanes);
         }
 
+        /**
+		 * Gets the world distance between the min and max points of the bounding box
+		 */
+		public get diagonalLength(): number {
+            let boundingBox = this.boundingBox;
+            let size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
+		    return size.length();
+		}     
+
         public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {
             return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
         }

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

@@ -470,7 +470,11 @@
 
         protected _afterBind(mesh: Mesh): void {
             this._scene._cachedMaterial = this;
-            this._scene._cachedVisibility = mesh.visibility;
+            if (mesh) {
+                this._scene._cachedVisibility = mesh.visibility;
+            } else {
+                this._scene._cachedVisibility = 1;
+            }
 
             this.onBindObservable.notifyObservers(mesh);
 

+ 1 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -713,7 +713,7 @@
         public _activate(renderId: number): void {
             this._renderId = renderId;
         }
-
+   
         /**
          * Returns the last update of the World matrix
          * Returns a Matrix.