Search code examples
javascriptrotationthree.jsscenegraph

Three.js - calculating relative rotations


I have a THREE.Scene with two meshes added, meshA and meshB, each of which has been rotated in different ways. My goal is to remove meshB from the scene and re-add it as a child of meshA, while preserving its global position and rotation -- in other words, the position and rotation of meshB should appear the same before and after this code.

My current, almost working attempt is as follows:

var globalOffset = new THREE.Vector3().subVectors( meshB.position, meshA.position );
var localOffset = meshA.worldToLocal( meshB.position );

var rotationOffset = meshA.quaternion.clone().inverse();
var rotation = meshB.quaternion.clone().multiply( rotationOffset );

scene.remove(meshB);
meshA.add(meshB);

meshB.position = localOffset;
meshB.rotation.setFromQuaternion(rotation);

The positioning works fine; the rotation only works if both meshA and meshB have been rotated around the same axis -- if meshA and meshB have been rotated around different axes, meshB appears to change rotation before and after this code.

Any ideas how I can correct the code above (or an idea for a different approach) so that meshB still has the same "global" rotation before and after being removed and re-added to the scene?

Thanks!


Solution

  • You want to remove meshB from the scene and re-add it as a child of meshA, while preserving its global position and rotation.

    You can do that like so:

    meshA.attach( meshB );
    

    three.js r.109