Possible to align TransformControls on arbitrary axes?

So instead of the controls being aligned to X, Y, and Z axes, can we orient the controls on axes, then transform on those axes?

@trusktr I have the same question, were you able to figure it out?

I have the same problem. Any news about this issue?

Is it possible overall? With slight modifications, yes.
Is it possible now? Nope. For what I see in the code only world and identity spaces are handled.

You can cheat around a little by changing the orientation of the worldQuaternion (with setMode('world') enabled on controls.) Create a duplicate of TransformControls and add setFromAxisAngle to parentQuaternion and worldQuaternion after this line:

Maybe there’s a simpler way, though I couldn’t find any :thinking:

Edit: Just as an example, since I can’t make a fiddle with custom controls:

parentQuaternion.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI / 2);
worldQuaternion.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI / 2);

parentQuaternionInv.copy( parentQuaternion ).inverse();
worldQuaternionInv.copy( worldQuaternion ).inverse();

Adding this will rotate the controls by 90° clockwise on Y-axis.

Thanks, but I could not get this working in my case. However, I found a simple solution for my problem:

I have a rotated Box which I want to display and be able to transform it and scale it along its rotated axes and not around the world axes (because when scaling it along the world axes its edges were not parallel anymore and it would no longer be a proper box).

I could solve it by adding a property called initialQuaternion to TransformControls and in the attach() function I set

this.object.quaternion.x = this.initialQuaternion[ 0 ];
this.object.quaternion.y = this.initialQuaternion[ 1 ];
this.object.quaternion.z = this.initialQuaternion[ 2 ];
this.object.quaternion.w = this.initialQuaternion[ 3 ];

If you choose setSpace(“local”), the controls are aligned with the given rotation and all transforms are applied in this frame. For setSpace(“world”) you can still translate and rotate the object around the world axes, but apply the scaling transform in the rotated frame.

In my case, I just had to make sure that the Box I attach to the TransformControls has zero rotation, because the rotation will be applied by the TransformControls already.

See: https://github.com/mrdoob/three.js/issues/19436

@reggie101 @asfg84 It turns out the camera controls read the camera’s up property. If you set up to the X axis (instead of the default Y) for example, then the controls will make the view’s up be along X so the left of the screen will be towards Y and right side will be towards -Y (or similar, maybe I have the negative sign backwards, but you get the idea).

Here is the docs on that: https://threejs.org/docs/index.html#api/en/core/Object3D.up

Cameras inherit from Object3D, and the camera controls use lookAt to make the camera look at objects (and lookAt depends on up).