Skip to content

Conversation

@trusktr
Copy link
Contributor

@trusktr trusktr commented Mar 6, 2020

The allows us to do camera.up = new Vector3(...) any time. Before, it could only be done one time before creating OrbitControls.

I'm not sure if there are any functional side-effects, or if it even works. I haven't tested it yet, but the main idea is that I wanted to try to set camera.up at some point after OrbitControls already exist, and found that it didn't do anything.

Also, if this does work, do I need to edit both OrbitControls files? Or does one get generated from the other?

// so camera.up is the orbit axis
var quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
var originalUp = new Vector3( 0, 1, 0 );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this value need to be the current default up (static property) of Object3D, whatever it is at any time? Or just the default up that THREE ships with by default?

@sciecode
Copy link
Contributor

sciecode commented Mar 7, 2020

Relevant #17857 (comment)

My original PR for merging trackball and orbit controls also supported this featured. Perhaps we could consider using that implementation when or if we decide to merge the controls into a single file.

/ping @mrdoob Is the process of stopping support for examples/js still in place?

@philipswan
Copy link

philipswan commented Dec 14, 2021

I could benefit from this change. If someone can resolve the conflicts and merge it, that would be awesome!!

For my use case, see: https://stackoverflow.com/questions/68061129/how-to-change-the-up-direction-on-the-fly-when-using-orbitcontrols-in-three-js

I actually tried this out locally, and found that there were changes such as switching from "var" to "const" and "invert" versus "inverse" that probably resulted in the merge conflicts. I ended up implementing something slightly different, and maybe better...

      // Calling code...
      camera.up = upVector     // Optional, but recommended
      orbitControls.upDirection = upVector
      orbitControls.update()
// Modifications to Orbit Controls...
		// Set to true to automatically rotate around the target
		// If auto-rotate is enabled, you must call controls.update() in your animation loop
		this.autoRotate = false;
		this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60

		// Initialize the up direction from the camera's up direction.
		this.upDirection = object.up.clone();
*
*
*
			//const quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
			//const quatInverse = quat.clone().invert();
			const quat = new Quaternion();
			const quatInverse = new Quaternion();
			const upDefault = new Vector3( 0, 1, 0 );

			const lastPosition = new Vector3();
			const lastQuaternion = new Quaternion();

			const twoPI = 2 * Math.PI;

			return function update() {

				// Will cause orbiting to occur around the upDirection vector
				quat.setFromUnitVectors( this.upDirection, upDefault );
				quatInverse.copy( quat ).invert();

				const position = scope.object.position;

@Mugen87 Mugen87 changed the title allow OrbitControl's camera.up to be modified at any time OrbitControl: Allow camera.up to be modified at any time. Apr 23, 2024
Fix `invert()` usage.
@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 23, 2024

To clarify this is the issue the PR tries to fix: https://jsfiddle.net/268unfyj/

The fiddle changes the camera's up vector to (0,0,1) after two seconds which breaks the interaction.

Here is a version of the fiddle that uses an embedded version of OrbitControls with the proposed fix: https://jsfiddle.net/268unfyj/2/

This version indeed retains the interaction. The following should be mentioned though: When the up vector is updated, the camera is transformed in the next update step to accommodate the new convention. This sudden "jump" could be considered as a bug but there is no way around it when the up vector changes and the controls rely on lookAt().

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 24, 2024

@WestLangley Do you see any fundamental issues with this PR?

@WestLangley
Copy link
Collaborator

the additional flexibility can be handy for devs like @philipswan.

Actually, this PR falls well-short of his specification:

What I need help with is reprogramming the orbit controls so that on the mouse click event: a) "Up" becomes a zenith-pointing vector where the user clicked on the globe b) The orbit controls target becomes the point on the globe where the user clicked... c) The act of clicking (and thus reprogramming the orbit controls) does not cause the scene to jump from the user's perspective.

After the orbit controls are reprogrammed, the user's experience should be that they can zoom in to the point on the globe where they clicked and orbit around that point naturally, as if they were flying around it in a drone.

This PR is not going to do that.

@Mugen87 wrote:

This sudden "jump" could be considered as a bug...

I agree completely. The behavior is also disconcerting IMO, especially when damping is enabled.

I do not see a compelling use case or demand for this PR as implemented. I expect a more natural implementation can be handled at the application level -- via two cameras, for example.

And, of course, the developer can always hack his own copy of OrbitControls.

@philipswan
Copy link

philipswan commented Apr 24, 2024

I fixed this in my own branch of OrbitControls a long time ago. The change I made works quite well. You can see the code I'm using here. I did this around two years ago so it might be easier to diff it against an older version of the Orbit Controls code. I think that I added an "upDirection" parameter and only a few lines of code were needed. I haven't seen any negative side effects from this change.

If you want to see it in action, there is an old version released here if you just want a quick preview. You can also sync up the whole project. There's a video on how to do that here. Or, you can just follow the directions in the Readme, and then read the directions in the "help" section of the GUI.

Search for case 80: /*P*/ in main.js. Hitting the 'P' key triggers a tweening operation that reorients the user to the desired location on the globe. Creating a smaller cleaner sample of this might be helpful to other users.

@Mugen87 Mugen87 closed this Apr 24, 2024
@Mugen87 Mugen87 added this to the r164 milestone Apr 24, 2024
@philipswan
Copy link

The link back to my original StackOverflow question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants