Orbit/MapControls mess up manual camera positioning

So I am working on a somewhat huge project right now and I have a function to reposition my camera in a way that it fits a visible Object3D/Group to the camera frustum.
Usually I control the camera with MapControls (or OrbitControls for that matter) and when setting the camera position via code the controls mess it up somehow.
I tried completely disabling the MapControls in which case the positioning is correct and all my debugging shows that the issue is definitely somewhere with the controls.

Here’s a short form of the code that manipulates the camera:

camera.position.set(intersection.x, intersection.y, intersection.z); //intersection is just a calculated Vector3
camera.updateProjectionMatrix();
mapControls.target.set(center.x, center.y, center.z);  //same goes for center
mapControls.update();

After executing this the difference between camera.position and intersection is non-zero on all three axes, which should not be the case - as far as I am aware, but maybe I am missing something.

I also tried disabling the mapControls before the manual change and re-enabling it right after, but that did not help.

Anyone knows how to solve this?

I doubt it’s the best (or only) solution, but so far I was able to solve this by setting the mapControls.object to a new PerspectiveCamera before I change the camera position, and once I am done manually changing the position of the existing camera, I change the mapControls.object back to the original camera.

That way the position updates correctly

mapControls.object = new THREE.PerspectiveCamera();
camera.position.set(intersection.x, intersection.y, intersection.z);
camera.updateProjectionMatrix();
mapControls.target.set(center.x, center.y, center.z);
mapControls.object = camera;

For manually setting the camera while having Orbit/MapControls, maybe it is worth trying this:

  • set restrictions for distance, polar angle and azimuth angle so the only available position of the camera is the specific point in space where you want it. For example, if this point is 5 units away from the target, set minDistance=5 and maxDistance=5. Do the same with min/maxPolarAngle and min/maxAzimuthAngle.
  • call controls’ update method, this will ask the controls to set the camera to the position that is locked by the min/max parameters.
  • release the min/max parameters locking

So, this is a kind of manual camera positioning by forcing the controls to position the camera where you want.

1 Like

I don’t see it in your example, are you calling camera.updateProjectionMatrix() after setting the camera position?

1 Like

Ah yeah I was just missing it in the example, my actual code has it. Thanks for the headsup

Still looking for help on this :face_holding_back_tears:

I still have the same suggestion:

  • restrict the camera to a point
  • ask the controls to update itself
  • and then release the restriction

As a proof of concept, here is a demo – when I click on the button, the camera positions itself against the white spot of the cube (it is on the negative X side of the cube) … and the controls happily continues from there.

Okay thanks. I guess that solution and the one with just using a dummy camera until it’s updated are the only proper options.
Thanks :slight_smile:

Oh, there are other options too (including writing your own OrbitControls).

Here is a link to my demo: https://codepen.io/boytchev/full/JjwGQwj

1 Like

Thank you a lot for the codepen.
Yeah I thought about my own orbitControls but that was like my last resort haha.