I have a parent Object containing a child Object
var parent1 = new THREE.Object3D();
parent1.rotation.set(1,2,3);
scene.add(parent1);
var child1= new THREE.Object3D();
child1.rotation.set(0.5,0.1,0.3);
parent.add(child1);
and another parent containing another child.
var parent2= new THREE.Object3D();
scene.add(parent2);
var child2= new THREE.Object3D();
childC2.rotation.set(3,1.15,2);
parent.add(child2);
Now I want to give child2
the same rotation as child1
by rotating it's parent2
.
As mentioned here, I can get the world-rotation from my original child1
like this:
var quaternion = new THREE.Quaternion();
child1.matrixWorld.decompose( new THREE.Vector3(), quaternion, new THREE.Vector3() );
and apply it to my parent2
like this:
parent2.quaternion.copy( quaternion );
Now parent2
has the same rotation like the original child1
, but I want it's child child2
to have have the same rotation like child1
(only by modifing parent2
)
I think this can be done by getting the difference of the world-rotation from parent2
and child2
and substracting this from the world-rotation of child1
, to correct the offset generated by the rotation of child2
.
But my knlowledge of quaternions and matrices is to bad to get it working.
Check out this fiddle, to understand my problem. Thanks a lot.
UPDATE
I tried the approach of WestLangley. If my Objects are only rotated around x-axis it works like this (see fiddle)
//calculate the relative rotation of child2
THREE.SceneUtils.detach( child2, parent2, scene );
var rotX=parent2.rotation.x-child2.rotation.x;
var rotY=parent2.rotation.y-child2.rotation.y;
var rotZ=parent2.rotation.z-child2.rotation.z;
THREE.SceneUtils.attach( child2, scene, parent2 );
//combine the relative rotation of child2 and the 'world' rotation of child1
THREE.SceneUtils.detach( child1, parent1, scene );
rotX+=child1.rotation.x;
rotY+=child1.rotation.y;
rotZ+=child1.rotation.z;
THREE.SceneUtils.attach( child1, scene, parent1 );
parent2.rotation.set(rotX,rotY,rotZ);//assign it to parent2
If my Objects are rotated around x,y,z this is NOT working anymore (fiddle). Is this a problem with gimbal lock? Do I need to do the calculation with quaternions instead of Euler Objects?
So you want to rotate a parent object so that the parent's child has a particular orientation, and you want that particular orientation to match the orientation of a child object of a different parent. Whew!
Here is one way to do that:
// detach the children from their parents and add them to the scene
THREE.SceneUtils.detach( child2, parent2, scene );
THREE.SceneUtils.detach( child1, parent1, scene );
// here is the tricky part: add the second parent as a child of its former child
THREE.SceneUtils.attach( parent2, scene, child2 );
// copy the first child's rotation, and make sure the matrix is updated
child2.rotation.copy( child1.rotation );
child2.updateMatrixWorld( true );
// detach the parent from the child and add it to the scene
THREE.SceneUtils.detach( parent2, child2, scene );
// put the children back where the were before
THREE.SceneUtils.attach( child2, scene, parent2 );
THREE.SceneUtils.attach( child1, scene, parent1 );
Here is a fiddle: http://jsfiddle.net/715v2hr1/
three.js r.68