LuisEgan
LuisEgan

Reputation: 1024

THREE.js Orbit controls zooming limits

I am using Orbit controls and they have a weird limit.

Zooming depends on the radius of the spherical coordinates of the camera relative to the orbiting axis. I'll try to explain how it works:

Everytime the user scrolls, the value of scale changes in this magnitude:

(if the user zooms in)

scale *= Math.pow(0.95, scope.zoomSpeed)

(or if user zooms out)

scale /= Math.pow(0.95, scope.zoomSpeed)

Then, the radius value changes with each update like this: spherical.radius *= scale

Then the scale value is reassigned its default value scale = 1 so the radius won't change with each update

The value of spherical.radius is what determines how close you are at what the camera is looking at so, of course, you have a limit when zooming in because the radius can only get so little (see that zooming in multiplies the radius value by .95, so it gets closer to 0 everytime)

The problem is if you zoom close to the orbiting axis (spherical.radius ~= 0), then rotate the camera and look down (or up or wherever) you can’t zoom into that direction because spherical.radius can't be any smaller!

So, my question is, how can I achieve that behavior (zooming up or down when the radius is at its limit) using Orbit controls.

P.S. This code can be found in OrbitControl.js of the THREE.js library, more specifically in the this.update() function. Here's the github repo

Upvotes: 2

Views: 3749

Answers (2)

LuisEgan
LuisEgan

Reputation: 1024

I managed to solve this thanks to pailhead (thanks again!)

Added the following to the this.update() function in OrbitControls.js

To get the vector where the camera is looking at

var cameraWorldDir = new THREE.Vector3();
scope.object.getWorldDirection(cameraWorldDir);

Magic:

if (spherical.radius <= 2) {
    scope.target.add(cameraWorldDir.multiplyScalar(0.4));
}

So, if I ever get close enough to the center, I just move the target (orbiting center) along the lookAt vector, aka I push it back.

See the full thread in the threejs forum here

Upvotes: 4

pailhead
pailhead

Reputation: 5431

You might be confused by the terminology used in OrbitControls

What "zoom" refers to is called "dolly" in the real world. It's a device used to create camera movements:

https://en.wikipedia.org/wiki/Camera_dolly

In the real world, "zooming a camera" means something different: https://en.wikipedia.org/wiki/Zooming_(filmmaking)

It requires changing the focal length of the lens to make the field of view narrower or wider (how much of the world you capture on screen from the same vantage point).

When you hit the minZoom value, you haven't actually done any zooming, you've got as close as you can to your orbit center.

You could try to disable the "zoom" or dolly on the OrbitControls and try to implement your own controller for just changing the camera.fov (zoom).

Upvotes: 2

Related Questions