Search code examples
javascriptthree.jsrotationposition

THREE JS get (world) rotation from matrixWorld


How do I get the world rotation of an Object3D in three.js? I know how to get the world position of an Object3D from object.matrixWorld, but how do I get the world rotation of an object?

I need this for the following problem: I have a hierarchical Object structure like this:

var obj1 = new THREE.Object3D();
obj1.x = 200;
obj1.rotation.x = 0.1;
scene.add(obj1);

var obj2 = new THREE.Object3D();
obj2.y = -400;
obj2.rotation.y = 0.21;
obj1.add(obj2);

var obj3 = new THREE.Object3D();
obj3.z = -200;
obj3.rotation.x = 0.1;
obj3.rotation.y = -0.1;
obj2.add(obj3);

Now I want to make my camera look at obj3 orthogonally in a certain distance. When My Objects are not rotated, this works like this:

var relativeCameraOffset = new THREE.Vector3(0, 0, 500); // 500 is z-distance from my object
var cameraOffset = relativeCameraOffset.applyMatrix4(obj3.matrixWorld);
camera.position = cameraOffset;

When only my last child is rotated I get what I want when I add this line

camera.rotation = obj3.rotation;

But when all parent Elements are rotated this is not working. So I'm looking for a way to get the world "orientation" of my 3D object. Thanks.


Solution

  • One way to get the "world" rotation is as follows:

    const position = new THREE.Vector3(); // create one and reuse it
    const quaternion = new THREE.Quaternion();
    const scale = new THREE.Vector3();
    
    mesh.matrixWorld.decompose( position, quaternion, scale );
    

    You can then set your camera orientation like so:

    camera.quaternion.copy( quaternion );
    

    Important: if you are going to access matrixWorld directly, you have to make sure it is updated. The renderer typically does this for you in the render loop. If, however, you are between render calls, and need to force an update of the matrix, you can do so with

    mesh.updateWorldMatrix( true, false );
    

    EDIT: There is another method that is now available. Check the source code so you see what it is doing.

    Object3D.getWorldQuaternion( targetQuaternion );
    

    three.js r.147