David Catuhe hace 8 años
padre
commit
64da21b7f5
Se han modificado 22 ficheros con 19582 adiciones y 19497 borrados
  1. 3821 3813
      dist/preview release/babylon.d.ts
  2. 36 36
      dist/preview release/babylon.js
  3. 46 26
      dist/preview release/babylon.max.js
  4. 3821 3813
      dist/preview release/babylon.module.d.ts
  5. 37 37
      dist/preview release/babylon.worker.js
  6. 5716 5707
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 31 31
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 46 26
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 5716 5707
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  10. 1 1
      dist/preview release/gui/babylon.gui.min.js
  11. 263 263
      dist/preview release/inspector/babylon.inspector.bundle.js
  12. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  13. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  14. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  15. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  16. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  17. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  18. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  19. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  20. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  21. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  22. 34 23
      src/Behaviors/Cameras/babylon.framingBehavior.ts

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3821 - 3813
dist/preview release/babylon.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 36 - 36
dist/preview release/babylon.js


+ 46 - 26
dist/preview release/babylon.max.js

@@ -10988,6 +10988,7 @@ var BABYLON;
         };
         Engine.prototype.deleteQuery = function (query) {
             this.deleteQuery(query);
+            return this;
         };
         Engine.prototype.isQueryResultAvailable = function (query) {
             return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT_AVAILABLE);
@@ -11002,6 +11003,7 @@ var BABYLON;
         Engine.prototype.endQuery = function (algorithmType) {
             var glAlgorithm = this.getGlAlgorithmType(algorithmType);
             this._gl.endQuery(glAlgorithm);
+            return this;
         };
         Engine.prototype.getGlAlgorithmType = function (algorithmType) {
             return algorithmType === BABYLON.AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE ? this._gl.ANY_SAMPLES_PASSED_CONSERVATIVE : this._gl.ANY_SAMPLES_PASSED;
@@ -11821,12 +11823,12 @@ var BABYLON;
             // Properties
             _this.definedFacingForward = true; // orientation for POV movement & rotation
             _this.position = BABYLON.Vector3.Zero();
-            _this.isOcclusionQueryInProgress = false;
             _this.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
             _this.occlusionType = AbstractMesh.OCCLUSION_TYPE_NONE;
             _this.occlusionRetryCount = -1;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
+            _this._isOcclusionQueryInProgress = false;
             _this._rotation = BABYLON.Vector3.Zero();
             _this._scaling = BABYLON.Vector3.One();
             _this.billboardMode = AbstractMesh.BILLBOARDMODE_NONE;
@@ -12017,6 +12019,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "isOcclusionQueryInProgress", {
+            get: function () {
+                return this._isOcclusionQueryInProgress;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -13875,14 +13884,14 @@ var BABYLON;
                 var isOcclusionQueryAvailable = engine.isQueryResultAvailable(this._occlusionQuery);
                 if (isOcclusionQueryAvailable) {
                     var occlusionQueryResult = engine.getQueryResult(this._occlusionQuery);
-                    this.isOcclusionQueryInProgress = false;
+                    this._isOcclusionQueryInProgress = false;
                     this._occlusionInternalRetryCounter = 0;
                     this._isOccluded = occlusionQueryResult === 1 ? false : true;
                 }
                 else {
                     this._occlusionInternalRetryCounter++;
                     if (this.occlusionRetryCount !== -1 && this._occlusionInternalRetryCounter > this.occlusionRetryCount) {
-                        this.isOcclusionQueryInProgress = false;
+                        this._isOcclusionQueryInProgress = false;
                         this._occlusionInternalRetryCounter = 0;
                         // if optimistic set isOccluded to false regardless of the status of isOccluded. (Render in the current render loop)
                         // if strict continue the last state of the object.
@@ -13901,7 +13910,7 @@ var BABYLON;
             engine.beginQuery(this.occlusionQueryAlgorithmType, this._occlusionQuery);
             occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
             engine.endQuery(this.occlusionQueryAlgorithmType);
-            this.isOcclusionQueryInProgress = true;
+            this._isOcclusionQueryInProgress = true;
         };
         // Statics
         AbstractMesh._BILLBOARDMODE_NONE = 0;
@@ -69917,7 +69926,7 @@ var BABYLON;
         function FramingBehavior() {
             this._mode = FramingBehavior.FitFrustumSidesMode;
             this._radiusScale = 1.0;
-            this._positionY = 0;
+            this._positionY = 1;
             this._defaultElevation = 0.3;
             this._elevationReturnTime = 1500;
             this._elevationReturnWaitTime = 1000;
@@ -70110,19 +70119,31 @@ var BABYLON;
          * @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, framingPositionY, focusOnOriginXZ) {
+        FramingBehavior.prototype.zoomOnMesh = function (mesh, focusOnOriginXZ) {
             if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
-            if (framingPositionY == null) {
-                framingPositionY = this._positionY;
-            }
             mesh.computeWorldMatrix(true);
+            this.zoomOnBoundingInfo(mesh.getBoundingInfo(), focusOnOriginXZ);
+        };
+        /**
+         * 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 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.zoomOnBoundingInfo = function (boundingInfo, focusOnOriginXZ) {
+            if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
             var zoomTarget;
-            var center = mesh.getBoundingInfo().boundingSphere.centerWorld;
+            var boundingBox = boundingInfo.boundingBox;
+            // Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+            var bottom = boundingBox.minimumWorld.y;
+            var top = boundingBox.maximumWorld.y;
+            var zoomTargetY = bottom + (top - bottom) * this._positionY;
             if (focusOnOriginXZ) {
-                zoomTarget = new BABYLON.Vector3(0, center.y, 0);
+                zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
             }
             else {
-                zoomTarget = center.clone();
+                zoomTarget = new BABYLON.Vector3(boundingBox.centerWorld.x, zoomTargetY, boundingBox.centerWorld.z);
             }
             if (!this._vectorTransition) {
                 this._vectorTransition = BABYLON.Animation.CreateAnimation("target", BABYLON.Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
@@ -70130,18 +70151,17 @@ var BABYLON;
             this._betaIsAnimating = true;
             this._animatables.push(BABYLON.Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 60, this._vectorTransition, this._framingTime));
             // 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._attachedCamera.lowerRadiusLimit = mesh.getBoundingInfo().boundingSphere.radiusWorld + this._attachedCamera.minZ;
-                    radius = position;
-                }
-                else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
-                    radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh);
-                    this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
-                }
+            // Small delta ensures camera is not always at lower zoom limit.
+            var delta = 0.1;
+            var radius = 0;
+            if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+                var position = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+                this._attachedCamera.lowerRadiusLimit = boundingInfo.boundingSphere.radiusWorld + this._attachedCamera.minZ;
+                radius = position;
+            }
+            else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                radius = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+                this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
             }
             // transition to new radius
             if (!this._radiusTransition) {
@@ -70156,8 +70176,8 @@ var BABYLON;
          * @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) {
-            var boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+        FramingBehavior.prototype._calculateLowerRadiusFromModelBoundingSphere = function (boundingInfo) {
+            var boxVectorGlobalDiagonal = boundingInfo.diagonalLength;
             var frustumSlope = this._getFrustumSlope();
             // Formula for setting distance
             // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3821 - 3813
dist/preview release/babylon.module.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 37 - 37
dist/preview release/babylon.worker.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 5716 - 5707
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 31 - 31
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 46 - 26
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -10988,6 +10988,7 @@ var BABYLON;
         };
         Engine.prototype.deleteQuery = function (query) {
             this.deleteQuery(query);
+            return this;
         };
         Engine.prototype.isQueryResultAvailable = function (query) {
             return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT_AVAILABLE);
@@ -11002,6 +11003,7 @@ var BABYLON;
         Engine.prototype.endQuery = function (algorithmType) {
             var glAlgorithm = this.getGlAlgorithmType(algorithmType);
             this._gl.endQuery(glAlgorithm);
+            return this;
         };
         Engine.prototype.getGlAlgorithmType = function (algorithmType) {
             return algorithmType === BABYLON.AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE ? this._gl.ANY_SAMPLES_PASSED_CONSERVATIVE : this._gl.ANY_SAMPLES_PASSED;
@@ -11821,12 +11823,12 @@ var BABYLON;
             // Properties
             _this.definedFacingForward = true; // orientation for POV movement & rotation
             _this.position = BABYLON.Vector3.Zero();
-            _this.isOcclusionQueryInProgress = false;
             _this.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
             _this.occlusionType = AbstractMesh.OCCLUSION_TYPE_NONE;
             _this.occlusionRetryCount = -1;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
+            _this._isOcclusionQueryInProgress = false;
             _this._rotation = BABYLON.Vector3.Zero();
             _this._scaling = BABYLON.Vector3.One();
             _this.billboardMode = AbstractMesh.BILLBOARDMODE_NONE;
@@ -12017,6 +12019,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "isOcclusionQueryInProgress", {
+            get: function () {
+                return this._isOcclusionQueryInProgress;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -13875,14 +13884,14 @@ var BABYLON;
                 var isOcclusionQueryAvailable = engine.isQueryResultAvailable(this._occlusionQuery);
                 if (isOcclusionQueryAvailable) {
                     var occlusionQueryResult = engine.getQueryResult(this._occlusionQuery);
-                    this.isOcclusionQueryInProgress = false;
+                    this._isOcclusionQueryInProgress = false;
                     this._occlusionInternalRetryCounter = 0;
                     this._isOccluded = occlusionQueryResult === 1 ? false : true;
                 }
                 else {
                     this._occlusionInternalRetryCounter++;
                     if (this.occlusionRetryCount !== -1 && this._occlusionInternalRetryCounter > this.occlusionRetryCount) {
-                        this.isOcclusionQueryInProgress = false;
+                        this._isOcclusionQueryInProgress = false;
                         this._occlusionInternalRetryCounter = 0;
                         // if optimistic set isOccluded to false regardless of the status of isOccluded. (Render in the current render loop)
                         // if strict continue the last state of the object.
@@ -13901,7 +13910,7 @@ var BABYLON;
             engine.beginQuery(this.occlusionQueryAlgorithmType, this._occlusionQuery);
             occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
             engine.endQuery(this.occlusionQueryAlgorithmType);
-            this.isOcclusionQueryInProgress = true;
+            this._isOcclusionQueryInProgress = true;
         };
         // Statics
         AbstractMesh._BILLBOARDMODE_NONE = 0;
@@ -49890,7 +49899,7 @@ var BABYLON;
         function FramingBehavior() {
             this._mode = FramingBehavior.FitFrustumSidesMode;
             this._radiusScale = 1.0;
-            this._positionY = 0;
+            this._positionY = 1;
             this._defaultElevation = 0.3;
             this._elevationReturnTime = 1500;
             this._elevationReturnWaitTime = 1000;
@@ -50083,19 +50092,31 @@ var BABYLON;
          * @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, framingPositionY, focusOnOriginXZ) {
+        FramingBehavior.prototype.zoomOnMesh = function (mesh, focusOnOriginXZ) {
             if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
-            if (framingPositionY == null) {
-                framingPositionY = this._positionY;
-            }
             mesh.computeWorldMatrix(true);
+            this.zoomOnBoundingInfo(mesh.getBoundingInfo(), focusOnOriginXZ);
+        };
+        /**
+         * 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 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.zoomOnBoundingInfo = function (boundingInfo, focusOnOriginXZ) {
+            if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
             var zoomTarget;
-            var center = mesh.getBoundingInfo().boundingSphere.centerWorld;
+            var boundingBox = boundingInfo.boundingBox;
+            // Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+            var bottom = boundingBox.minimumWorld.y;
+            var top = boundingBox.maximumWorld.y;
+            var zoomTargetY = bottom + (top - bottom) * this._positionY;
             if (focusOnOriginXZ) {
-                zoomTarget = new BABYLON.Vector3(0, center.y, 0);
+                zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
             }
             else {
-                zoomTarget = center.clone();
+                zoomTarget = new BABYLON.Vector3(boundingBox.centerWorld.x, zoomTargetY, boundingBox.centerWorld.z);
             }
             if (!this._vectorTransition) {
                 this._vectorTransition = BABYLON.Animation.CreateAnimation("target", BABYLON.Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
@@ -50103,18 +50124,17 @@ var BABYLON;
             this._betaIsAnimating = true;
             this._animatables.push(BABYLON.Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 60, this._vectorTransition, this._framingTime));
             // 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._attachedCamera.lowerRadiusLimit = mesh.getBoundingInfo().boundingSphere.radiusWorld + this._attachedCamera.minZ;
-                    radius = position;
-                }
-                else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
-                    radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh);
-                    this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
-                }
+            // Small delta ensures camera is not always at lower zoom limit.
+            var delta = 0.1;
+            var radius = 0;
+            if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+                var position = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+                this._attachedCamera.lowerRadiusLimit = boundingInfo.boundingSphere.radiusWorld + this._attachedCamera.minZ;
+                radius = position;
+            }
+            else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+                radius = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+                this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
             }
             // transition to new radius
             if (!this._radiusTransition) {
@@ -50129,8 +50149,8 @@ var BABYLON;
          * @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) {
-            var boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+        FramingBehavior.prototype._calculateLowerRadiusFromModelBoundingSphere = function (boundingInfo) {
+            var boxVectorGlobalDiagonal = boundingInfo.diagonalLength;
             var frustumSlope = this._getFrustumSlope();
             // Formula for setting distance
             // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 5716 - 5707
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 263 - 263
dist/preview release/inspector/babylon.inspector.bundle.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


+ 34 - 23
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -6,7 +6,7 @@ module BABYLON {
 
         private _mode = FramingBehavior.FitFrustumSidesMode;
         private _radiusScale = 1.0;
-        private _positionY = 0;
+        private _positionY = 1;
         private _defaultElevation = 0.3;
         private _elevationReturnTime = 1500;
         private _elevationReturnWaitTime = 1000;
@@ -204,20 +204,32 @@ module BABYLON {
 		 * @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, framingPositionY?: number, focusOnOriginXZ: boolean = false): void {
-			if (framingPositionY == null) {
-				framingPositionY = this._positionY;
-			}
-
+		public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false): void {
 			mesh.computeWorldMatrix(true);
-			
+
+			this.zoomOnBoundingInfo(mesh.getBoundingInfo(), focusOnOriginXZ);
+		}
+
+		/**
+		 * 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 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 zoomOnBoundingInfo(boundingInfo: BoundingInfo, focusOnOriginXZ: boolean = false): void {
 			let zoomTarget: BABYLON.Vector3;
-			let center = mesh.getBoundingInfo().boundingSphere.centerWorld;
+			let boundingBox = boundingInfo.boundingBox;
+
+			// Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
+			let bottom = boundingBox.minimumWorld.y;
+			let top = boundingBox.maximumWorld.y;
+			let zoomTargetY = bottom + (top - bottom) * this._positionY;
 
 			if (focusOnOriginXZ) {	
-				zoomTarget = new BABYLON.Vector3(0, center.y, 0);
+				zoomTarget = new BABYLON.Vector3(0, zoomTargetY, 0);
 			} else {
-				zoomTarget = center.clone();
+				zoomTarget = new BABYLON.Vector3(boundingBox.centerWorld.x, zoomTargetY, boundingBox.centerWorld.z);
 			}
 
 			if (!this._vectorTransition) {
@@ -229,17 +241,16 @@ module BABYLON {
 									60, this._vectorTransition, this._framingTime));
 
 			// 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._attachedCamera.lowerRadiusLimit = mesh.getBoundingInfo().boundingSphere.radiusWorld + this._attachedCamera.minZ;
-					radius = position;
-				} else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
-					radius = this._calculateLowerRadiusFromModelBoundingSphere(mesh);
-					this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
-				}
+			// Small delta ensures camera is not always at lower zoom limit.
+			let delta = 0.1;
+			let radius = 0;
+			if (this._mode === FramingBehavior.FitFrustumSidesMode) {
+				let position = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+				this._attachedCamera.lowerRadiusLimit = boundingInfo.boundingSphere.radiusWorld + this._attachedCamera.minZ;
+				radius = position;
+			} else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
+				radius = this._calculateLowerRadiusFromModelBoundingSphere(boundingInfo);
+				this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
 			}
 
 			// transition to new radius
@@ -258,8 +269,8 @@ module BABYLON {
 		 * @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): number {
-            let boxVectorGlobalDiagonal = mesh.getBoundingInfo().diagonalLength;
+		protected _calculateLowerRadiusFromModelBoundingSphere(boundingInfo: BoundingInfo): number {
+            let boxVectorGlobalDiagonal = boundingInfo.diagonalLength;
 			let frustumSlope: BABYLON.Vector2 = this._getFrustumSlope();
 
 			// Formula for setting distance