Alex Wayne Alex Wayne - 3 years ago 183
CoffeeScript Question

Invert rotation of parent in the child, so the child appears unrotated in the world

In a THREE.js scene, I have a parent object that rotates around. This parent has children that should be positionally locked to their parent's rotation, but their own rotation needs to be independent and not inherit from the parent.

A simple case would be to make the children always face the camera.

My attempt was to "invert" the rotation of the parent in the children. That is:

# render loop
render = ->

# Rotate the parent
@parent.rotation.x += 0.01
@parent.rotation.z += 0.02

# Attempt to invert rotation of the parent, and fail :(
for child in @children
child.rotation.x = -@parent.rotation.x
child.rotation.z = -@parent.rotation.z

The result of this naive attempt is here. The small yellow planes are children of the gray cube, and they rotate around in ways I wouldn't expect...

What I want is those planes to be perfect squares the whole time, moving with the rotation of the cube, but with their rotation locked to the world, and not the parent.

So how would I undo the rotation of the parent in the child? What crazy math am I missing here?

I know I could be using point sprites for this example, but I have more complex needs in mind eventually where point sprites just won't do. So I need to figure out to do this with a real 3D object.

EDIT: This does work for each axis alone. If the parent only rotates on X, I can invert that on the child's X rotation and it's just like I want. Same for only Z. However, if I start to vary and then invert both X and Z it then gets all squirrely.

Answer Source

There is always a trick. :-)

You want to have children of a parent object whose positions are relative to the parent, but whose rotations are independent of the parent.

The easiest way to do this is to have dummy Object3D objects as children of the parent and then add the children to the scene (not the parent) and have the children get their world positions from the dummy objects.

parent                 scene
   |                     |
   --- object_1          --- child_1
   |                     |
   --- object_2          --- child_2

child_1.position is set from object_1's world position:

child.position.setFromMatrixPosition( parent.children[ idx ].matrixWorld )

As an alternative, there is a THREE.Gyroscope that you could use, but it is computationally more intensive.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download