# ArcRotateCamera.zoomOn is not working as expected

**URL:** <https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649>\
**Category:** Bugs\
**Tags:** camera\
**Created:** [February 24, 2021, 4:51pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649 "2021-02-24T16:51:56Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![wang.minion](https://avatars.discourse-cdn.com/v4/letter/w/e5b9ba/32.png) [@wang.minion](https://forum.babylonjs.com/u/wang.minion)\
**Post date:** [February 24, 2021, 4:51pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/1 "2021-02-24T16:51:56Z")

</div>

ArcRotateCamera.zoomOn is not working as expected.

If I have a large viewport, I see that there is still a bit more to be zoomed there.  
If I reduce the viewport, and call the function again, nothing updates and the object doesn’t fit.

I want to use this to automatically zoom the camera in the initial load to fit the viewport.

[https://playground.babylonjs.com/#IYPUNY](https://playground.babylonjs.com/#IYPUNY)

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [February 24, 2021, 5:08pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/2 "2021-02-24T17:08:43Z")

</div>

adding @Cedric to check 😉

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [February 24, 2021, 5:23pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/3 "2021-02-24T17:23:47Z")

</div>

I’m taking a look.

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [February 24, 2021, 5:33pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/4 "2021-02-24T17:33:25Z")

</div>

@wang.minion

`zoomOn` function places the cameras so the distance to the bounding box center of the mesh is large enough to not have the camera in the bounding box.  
to make it short, it places the camera, so it’s far enough of the bounding box.

It doesn’t take into account the projected bounding box, the camera fov or the viewport size.

---

<div class="post-metadata">

**Author:** ![wang.minion](https://avatars.discourse-cdn.com/v4/letter/w/e5b9ba/32.png) [@wang.minion](https://forum.babylonjs.com/u/wang.minion)\
**Post date:** [February 24, 2021, 5:36pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/5 "2021-02-24T17:36:49Z")

</div>

> [@Cedric](#):
>
> enough

Thanks for letting me know about that.  
In that case, if I want to zoom in/out automatically the camera to fit the current viewing bounding box, what could I do?  
Do I have to manually calculate the ArcRotateCamera’s alpha, beta, radius?

Looking forward to your solutions.

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [February 24, 2021, 5:42pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/6 "2021-02-24T17:42:43Z")

</div>

alpha/beta can be updated just by setting the target (center of bounding box).  
The real deal is to set the distance to the center that will give the projected bounding box to be entierly framed by the viewport.  
as usual depending on the quality, this will need some work.  
if you assume the bounding sphere is enough, then you can compute the distance so the projected disk is framed by the viewport.  
for the viewport, you only need the ratio width/height I think. the closer to 1, the more you can zoom.  
and use the fov value from the camera aswell.

---

<div class="post-metadata">

**Author:** ![wang.minion](https://avatars.discourse-cdn.com/v4/letter/w/e5b9ba/32.png) [@wang.minion](https://forum.babylonjs.com/u/wang.minion)\
**Post date:** [March 3, 2021, 5:34pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/7 "2021-03-03T17:34:51Z")

</div>

@Cedric, quick question around the `fov`. So what I have found out is that `fov` is the `dfov`.  
Please check the article I have sent below.  
[http://chrisjones.id.au/FOV/fovtext.htm](http://chrisjones.id.au/FOV/fovtext.htm)

So what I did was that I set the `fovMode` of ArcRotateCamera as `FIXED`.

```auto
defaultCamera.fovMode = ArcRotateCamera.FOVMODE_HORIZONTAL_FIXED

```

And calculated the `hfov` and `vfov` from `dfov` and based on that, I calculated the `radius`.  
Is this the right choice?  
It seems working but still shows some paddings.

Please let me know if that makes sense.

```auto
export function zoomOnCamera (mesh: Mesh, camera: ArcRotateCamera) {
  camera.fovMode = ArcRotateCamera.FOVMODE_HORIZONTAL_FIXED

  const { max, min } = mesh.getHierarchyBoundingVectors(true, x => x.isVisible)
  const boundingInfo = new BoundingInfo(min, max)
  const bbox = boundingInfo.boundingBox
  const ratio = camera.getScene().getEngine().getAspectRatio(camera, true)

  const dfov = camera.fov

  const vfov = Math.atan(Math.tan(dfov / 2.0) * Math.cos(Math.atan(ratio))) * 2.0
  const vtheta = vfov / 2
  const vr = (bbox.maximum._y - bbox.minimum._y) / 2
  const vdistance = vr / Math.sin(vtheta)

  const hfov = Math.atan(Math.tan(dfov / 2.0) * Math.sin(Math.atan(ratio))) * 2.0
  const htheta = hfov / 2
  const hr = (bbox.maximum._x - bbox.minimum._x) / 2
  const hdistance = hr / Math.sin(htheta)

  camera.radius = Math.max(hdistance, vdistance)
}

```

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [March 3, 2021, 5:46pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/8 "2021-03-03T17:46:50Z")

</div>

I don’t think vr and hr are correct. it’s computed with world coordinates but your camera can be oriented so x is not on the camera right.

---

<div class="post-metadata">

**Author:** ![wang.minion](https://avatars.discourse-cdn.com/v4/letter/w/e5b9ba/32.png) [@wang.minion](https://forum.babylonjs.com/u/wang.minion)\
**Post date:** [March 4, 2021, 8:35am UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/9 "2021-03-04T08:35:50Z")

</div>

So

- Regarding `fov` of ArcRotate Camera as a `dfov` is the right decision?
- And you mean `vr` and `hr` calculations are not proper?

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [March 4, 2021, 1:28pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/10 "2021-03-04T13:28:20Z")

</div>

depending on the camera fovmode (vertical or horizontal) I would compute the other value instead of using a dfov. [https://www.reddit.com/r/Planetside/comments/1xl1z5/brief\_table\_for\_calculating\_fieldofview\_vertical/](https://www.reddit.com/r/Planetside/comments/1xl1z5/brief_table_for_calculating_fieldofview_vertical/)

vr and hr should use the camera orientation. Or, for a first test, compute a maximum radius and use it for both.

---

<div class="post-metadata">

**Author:** ![wang.minion](https://avatars.discourse-cdn.com/v4/letter/w/e5b9ba/32.png) [@wang.minion](https://forum.babylonjs.com/u/wang.minion)\
**Post date:** [March 4, 2021, 1:47pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/11 "2021-03-04T13:47:10Z")

</div>

Great. Thanks for this.

---

<div class="post-metadata">

**Author:** ![aidenn](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/aidenn/32/22606_2.png) [@aidenn](https://forum.babylonjs.com/u/aidenn)\
**Post date:** [August 25, 2022, 8:43pm UTC](https://forum.babylonjs.com/t/arcrotatecamera-zoomon-is-not-working-as-expected/18649/12 "2022-08-25T20:43:26Z")

</div>

Looking into doing something similar, and I was wondering if you ever got this working in a playground?
