For the past week I’ve been working on enabling head tracking. Head tracking allows actors to orient their head towards any point in the game world. This work is now included in PR #947.
The head tracking works by reorienting one of the bones of the skeleton after keyframe animation is applied. The bone is oriented to face the direction the actor wants to look towards. The look direction is interpolated, so the change in orientation is not instant.
The original Lua code uses the functions ActorSetHead and ActorSetHeadLimits to set up head tracking. The former takes as parameter the name of the bone that should be animated, while the latter takes three parameters that specify horizontal and vertical angle limits. The angle limits ensure that the head won’t be oriented unrealistically.
My current implementation looks good in most cases, but I did find one case that looks noticeably different from the original. Mr. Cheese’s head is at a weird angle when he looks towards Guybrush in the Scumm Bar. The screenshot on the left is ResidualVM, while the one on the right is the original.
The head tracking animates Mr. Cheese’s neck bone, but the neck bone has children which are animated by keyframe animation, and the vertices of the head mesh follow the child bones. Although the neck bone is facing Guybrush, the head mesh is not, because of the animation applied to the child bones.
I spent a significant amount of time trying to figure out the difference between my implementation and the original during the week, but none of my solutions produced the same result as the original in this case.
One of my attempts was to override the animation of the neck bone as well as it’s children bones completely whenever head tracking is active. This way the head was oriented exactly towards the point the actor looks at. That, however, didn’t match the original game either. Mr. Cheese’s head does seem to be affected by the animation also in the original.
For now I decided to leave this be. Mr. Cheese is currently the only case I’m aware of where the result is different from the original. I may return to this at a later stage once I’ve finished the other remaining tasks.