Imagine I have this hierarchy of groups:
Grandpa= new THREE.Group();
Parent= new THREE.Group(); Grandpa.add(Parent);
Child = new THREE.Group(); Parent.add(Child);
Now imagine we set some rotations in different rotation axis for both Grandpa and Parent. Each has its own rotation.
How can I make Child group rotate and point to a certain direction (lookAt) in absolute world coordinates, and not referenced to its parent(s)?
P.S: In my real code the hierarchy is much longer than 2 parents.
Have you tried detaching the child from it’s parent, applying the rotation, then reattaching it?
scene.add( child );
child.lookAt( thing );
parent.add( child );
Note I haven’t actually tried this, and if the parent’s rotation is changed after the child is added it will obviously affect the child, breaking the lookAt. But it might be worth a try.
Thanks @looeee for the reply. However it does not work
I don’t have the chance to do what you propose since when I load the model the hierarchy of objects is already loaded. So I can’t detach the objects…
If you can call
object .lookAt on the object, you can call
scene.add( object ), which automatically detaches the object.
The object is a THREE.skeleton, and I am trying to move the bones in absolute direction…
Adding to the scene does not generally preserve world position. This answer used to include an immensely popular link to SceneUtils’
detach functions. As of release 105 they are now superseded by
Object3D.attach. Quoting the documentation for Object3D:
.attach ( object : Object3D ) : this
Adds object as a child of this, while maintaining the object’s world transform.
(originally defined in https://github.com/mrdoob/three.js/pull/16528)
SceneUtils.detach(object, parent, scene) can be replaced by
scene.attach(object), (at least if the scene is untransformed. Not sure they are 100% equivalent otherwise.).
In the longer run, it is useful to learn how the local and global matrices (and their inverses!) work and can be manipulated.
The local matrix of an object encodes local position, scale and rotation (and possibly more). The world matrix of an object is the matrix product of all local matrices of direct ancestors and the object itself, and encodes the combined effects of the matrices, including global position.
Applying the inverse of a matrix gives the inverse transform. This can for instance be used for finding an object’s position in another object’s local coordinates. Apply the inverse of the world matrix of the second object to the world position of the first.
Object3D has helpers like
lookAt), and there are other useful methods in
Vector3 and more, I recommend reading the sources too see what is going on, and then soon you can write handy helper functions for your own needs.
Thanks, I didn’t know about the attach / detach functions!