[Solved] Transform controls with orthographic camera : gizmos scale problem

Hello,
I’m using an Orthographic camera with OrbitControls. I noticed that when zooming the value of camera.zoom changes not the position of the camera (like in Perspective camera) .
First I’m curious to understand why it is implemented differently in the two cameras :nerd_face: ?

Second I’m also using TransformControls and in the case of Perspective camera the rescale of the gizmos on the update function worked great with this equation :
scale = worldPosition.distanceTo(camPosition) / 6 * scope.size;
But with OrbitControls changing the zoom not the position of the Orthographic camera it is not working as it should. I tried adding the zoom in the equation like this but didn’t get any good results :
scale = (camera instanceof THREE.OrthographicCamera) ? worldPosition.distanceTo(camPosition) / (6 * scope.size * camera.zoom) : worldPosition.distanceTo(camPosition) / 6 * scope.size;
Should I include it differently ?
Should I use other controls ?
Thank you all for your help !

2 Likes

AFAIK, that has historical reasons. OrbitControls started with support for perspective cameras first. When support for orthographic cameras was added, the class needed a different implementation for zoom. Keep in mind that orthographic cameras have no perspective. Moving the camera along the look direction (dollying) does not magnify/minify objects. Because of this, zooming in OrbitControls with an orthographic camera indirectly changes the projection matrix.

What does that mean? Can you please be more specific? Can you show a live example with your current progress?

Thanks for the reply and the explanation!
Here is the example with a Perspective Camera .
Here is the example with an Orthographic Camera .
The difference is the size of the transform controls gizmos :

  • With a perspective camera the size is relative to the screen and doesn’t change on the screen when zooming and dezooming .
  • With the orthographic camera the size changes when you zoom/dezoom (bigger/smaller).

This is due to the rescaling of the transform controls in the function update() in TransformControls.js.

scale = worldPosition.distanceTo(camPosition) / 6 * scope.size;

The equation to change the scale in the update function only takes into account the distance between the camera and the transform controls. So if the zoom doesn’t affect the position (in the case of ortho) the rescaling doesn’t work.
I’m thinking of how to add camera.zoom into the equation so it would behave as it does with perspective camera.

Check out if the upcoming version of TransformControls solves your problem.

I’ve update your fiddle with a simple enhancement for orthographic cameras (have a look at the mentioned scale calculation): https://jsfiddle.net/gvj2cm1k/163/

Maybe this helps a bit.

I think this terminology should be clarified so to not introduce any more confusion.

Zooming is not the same as dollying.

Imagine you have a digital camera, and you stand on a chair. You look around and you want to zoom in/out. You press the +/- buttons on the camera, and the view through the view finder changes size. You’re still standing on the chair.

If the controls did the same thing conceptually as the orthographic controls, you would be zooming in/out in both controllers.

It could make more sense if you consider this invalid:

Keep in mind that orthographic cameras have no perspective.

And say:

Keep in mind that an orthographic camera is just a perspective camera with an infinitely small FOV.

This might make more sense. If you make a really high resolution perspective rendered image and start cropping it, you’re zooming in. If you render an image at a narrow FOV, and then superimpose it on an image rendered with a bigger FOV it will match a region.

The same happens with an Orthographic camera.

My stab at this would be

lack of vision

Not meant to berate anyone. But think about what you’re asking:

  1. not part of three.js
  2. community provided example
  3. evolved over many years

Meaning, people added bits and pieces over a long period of time. Three.js was not the same three.js when this component started out.

A vision would be:

  1. foo shares X with bar - refactor
  2. Apples are called penguins - refactor
  3. users are asking for baz - refactor

Which means, it’s waiting for someone, to fix this :slight_smile:

You or anyone else can make a PR and it may or may not be accepted.

If you fork this and make it public, you can define the behavior any way you want.

I think this may be enough for you:

scale = (camera instanceof THREE.OrthographicCamera) ? 
  1 / (scope.size * camera.zoom) : 
  worldPosition.distanceTo(camPosition) / 6 * scope.size;

Thanks i’m gonna check it out :smiley:.

Actually it helped a lot thanks ! I’m still figuring something more suitable for my project but you put me on the right path. I’ll post it here when i’m done. :slightly_smiling_face:
[Edit] : I just added a coefficient to make it bigger but your solution worked perfectly! Thanks a lot!

I didn’t mention this in my post but i just started exploring three.js and using it to do some projects. My question is only for the purpose of understanding more the library … I’m clearly not criticising :sweat_smile:

I’m still a noobie i need to undestand how things work first (in the library and also in the community) but sure when I achive a certain level of understading I’ll do that.

Thanks i’ll try it out!

I was trying to be very specific, it might be my opinion but the library refers to the source three.js object, like when you import three.min.js everything else is a community provided example.

1 Like