-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OrbitControls: Add zoom to cursor #26165
Conversation
// get the ray and translation plane to compute target | ||
const ray = new Ray(); | ||
ray.origin.copy( scope.object.position ); | ||
ray.direction.set( 0, 0, - 1 ).transformDirection( scope.object.matrix ); | ||
|
||
const plane = new Plane(); | ||
plane.setFromNormalAndCoplanarPoint( scope.object.up, scope.target ); | ||
|
||
ray.intersectPlane( plane, scope.target ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general approach is to move the camera such that the point under the cursor is visually consistent after zooming and the target is moved to accommodate this camera position movement.
However - when using non-screenspace panning and trying to zoom to cursor when the camera is looking parallel to the plane this portion of code fails because we're using the camera ray and plane to determine where to place the target. Any recommendations? Should we just disable zoom to cursor when the dot product of the plane normal and ray is under some threshold? Then we can recommend that users limit the angles in these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should make it so that when you're parallel and zoom "towards the sky", we pick an arbitrary distance away and use that as if we had collided with the terrain, then use the same code. I.e. dolly the camera in that direction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this won't work since the camera always has to face the target point. This means the camera will move up into the sky and then arc down towards the view point since the target has to stay on that plane - which isn't necessarily what someone would expect.
Zoom to cursor with map controls only really makes sense when limiting the camera control angles, imo, but we should have some approach that doesn't break here. Perhaps the arcing is okay in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw,
since the camera always has to face the target point
how can you possibly maintain both target and the point under cursor constraints? one of them will fail as soon as you move persp. camera in any way other than rotating around the axis formed by those 2 points.
|
||
function clampDistance( dist ) { | ||
|
||
return Math.max( scope.minDistance, Math.min( scope.maxDistance, dist ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could reuse the clamp function available in MathUtils
cc @WestLangley @Mugen87 - I think this is ready for review. I have questions on the following:
And this comment: #26165 (comment) |
…sing a stale ray with pinch
No, I wouldn't do that.
TBH, I'm not sure what to recommend here. Do whatever you think is best at the moment. We can still change it at a later point if necessary. |
Okay I've just updated the controls so we don't move the camera target if zooming to cursor when the camera is 20 degrees above the horizon. This means the camera can rotate a bit during zoom (only in that corner case) but at least the target position doesn't immediately scale out of control. It's best for users to limit the altitude angle when zoomToCursor and screenSpacePanning are enabled, anyway. Imo this is ready to merge unless someone catches something new! |
This comment was marked as off-topic.
This comment was marked as off-topic.
I was expecting this feature to be released in r154, any update? |
Let's merge this to give this implementation a chance in prod! |
I'm testing this feature and I was experiencing weird behaviors with zoom limits, was able to fix it by setting |
If you don't show or specify what "weird behaviors" are then nothing can be done... |
Yes sorry, I don't think it's really a bug but the intended behavior with So maybe it should be mentioned that when using |
wait, are you saying it does not respect controls.minDistance @alessiocancian |
No it does respect it, that's why I get stuck. By stuck I mean that I cannot zoom in anymore, but I can still zoom out. |
This is how OrbitControls has always worked so this shouldn't be surprising. When you zoom in within the |
} else if ( scope.object.isOrthographicCamera ) { | ||
|
||
// adjust the ortho camera position based on zoom changes | ||
const mouseBefore = new Vector3( mouse.x, mouse.y, 0 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkjohnson I think mouseBefore
should have been instantiated once inside the closure.
Likewise, mouseAfter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! You're right. That would be a good change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkjohnson Something like this.
mouseBefore.set( mouse.x, mouse.y, 0 ).unproject( scope.object );
...
mouseAfter.set( mouse.x, mouse.y, 0 ).unproject( scope.object );
...
scope.object.updateWorldMatrix( false, false ); // if you say it is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good change but this PR is already merged and I have other priorities at the moment. I'm happy to review a PR from anyone else to get it in, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand the code block, so it will not be me.
Fixed #22522.
Related PRs: #24983, #17145, #23254
Description
Another effort to get map-like zoom to cursor working with OrbitControls. Some of the other efforts were not sufficient from what I could tell. I tried a few different approaches and seemed to be suffering from numeric precision issues before I landed on this one.
A question:
In Progress:
Handle initially unset or 0 distance to targetSimplify zoom cases with non camera objectsFix non-cursor zooming with ortho camerascc @WestLangley @Mugen87