Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js - Rotation not respecting local orientation

I'm using a large array of objects built around a center point in a scene, and need to manipulate them all around their local axis. They are all facing the origin using a blank object and lookAt(), then I used this method to align the other axes correctly. Getting the initial rotation this way worked great, unfortunately when I try to rotate these objects on the fly with object.rotation.x = <amount>, it does not respect the local axis of the object.

The confusing part is, it's not even using the global axis, the axis it's using almost seems entirely arbitrary. I set up a JSFiddle to demonstrate this here. As you can see on line 129, looker.rotation.z works correctly, it rotates along the Z axis properly, but if it's changed to X or Y, it doesn't rotate along local or global axes. If anyone could demystify what is happening to cause this, that would be great.

like image 607
Hobo Joe Avatar asked Feb 14 '23 21:02

Hobo Joe


1 Answers

What is happening is that you want to add some rotation to the current orientation, and setting the variable looker.rotation.z means other thing.

At the end, to calculate the rotation matrix of the looker, there will be something like (pseudocode: the functions are not these, but you get the idea):

this.matrix.multiply( makeXRotationMatrix(this.rotation.x) )
this.matrix.multiply( makeYRotationMatrix(this.rotation.y) )
this.matrix.multiply( makeZRotationMatrix(this.rotation.z) )
DrawGeometry(this.geom, this.matrix)

and composition of rotations are not intuitive. This is why it doesn't seem to follow any axis system.

If you want to apply a rotation in some axis to the existing matrix, it can be made with the functions rotateX (angle), rotateY (angle), rotateZ (angle), and rotateOnAxis (axis, angle). axis can be a THREE.Vector3.

Changing directly looker.rotation.z works because it is the nearest rotation to the geometry, and it will not be affected by the other rotations (remember that transformation matrices apply in inverse order, e.g. T*R*G is Rotating the Geometry, and then, Translating it).

Summary

In this case I suggest not to use the line:

looker.rotation.z += 0.05;

Use

looker.rotateZ (0.05);

or

looker.rotateX (0.05);

instead. Hope this helps :)

like image 158
jmmut Avatar answered Feb 23 '23 20:02

jmmut