1
votes

Orbit controls are great, but they have the limitation that the Y axis always points UP on the screen.

I want to add a "roll" to the camera and retain it while orbiting. If I change the camera.up vector it will add a roll but as I orbit around the object the appearance of the roll vector changes. e.g. If it starts tilted to the left on the screen, when I orbit around to the other side the camera.up is unchanged, but it now tilts to the right on the screen.

I noticed this is exactly how the camera works in Blender, per screenshot.

enter image description here

Any idea how to achieve this in threejs?

(Bonus points: In Blender the orbit control is also able to continue orbiting smoothly over the top of the sphere, whereas the orbit control in three.js gets stuck at the top of the sphere. It would be great to know that too)

2
I suspect one approach is to dynamically calculate what camera.up would be required to give a particular screen up direction and apply it each frame, similar to stackoverflow.com/a/34209101/1767169 but with camera.up varying, not fixed.python1981
Looking over code for how both Orbit and Trackball are handled in Blender, in github.com/BSVino/Blender/blob/…python1981
Do you want the camera to always rotate around the Y-axis but have the camera tilt so it is not level? If so, why? What is your use case?WestLangley
Yes @WestLangley that's right. I want to keep the intuitiveness & precision of the Orbit controller for aligning the 3D scene to match a photo. Keeping the rotation around the Y-axis means the user always knows what an orbit will do without needing to factor in what impact the up-direction will have. Orbit & Trackball controls in blender seem to be somewhat more sophisticated... would it be useful to create new controllers that use the blender approach/math?python1981
Is this what you mean? jsfiddle.net/ar5rfydjWestLangley

2 Answers

2
votes

TrackballControls for threejs does what you want: Y-Axis not always UP and you can orbit over the top.

This is the official example: https://threejs.org/examples/?q=trackbal#misc_controls_trackball

1
votes

You can use OrbitControls and "tilt" the camera using a pattern like so:

var tilt = Math.PI / 8;
camera.rotation.order = 'YXZ';

In your animation loop, do this:

controls.update();
camera.rotation.z = tilt;

This works because, with rotation.order set to YXZ, the camera orientation, as set by OrbitControls, has camera.rotation.z = 0. So in this case, there is no harm in changing it.

fiddle: http://jsfiddle.net/ar5rfydj/

three.js r.86