Object Placement On Avatar Sample

This sample shows how to draw a model on part of an avatar. In this case, a baseball bat is placed in the avatar's right hand.

Sample Overview

Occasionally, you may want the avatars in your game to interact with other objects in the world. For example, perhaps you want your avatar to hold a baseball bat. In order to draw the baseball bat in the correct location, you need to know the world space location at which to place the bat. This sample demonstrates how to find the world space transform that is needed to draw a baseball bat in the avatar's right hand.

Sample Controls

This sample uses the following gamepad controls.

Action Gamepad control
Play cheer animation A
Play clap animation B
Play stand animation Y
Play stand 5 animation X
New random avatar Right bumper
Rotate the camera Right thumb stick
Zoom in Right trigger
Zoom out Left trigger
Reset the camera Right thumb stick press
Exit the sample BACK

How the Sample Works

In order to place an object near part of the avatar, you need to create a world space transform to draw the model. In this case, you are trying to draw a baseball bat model near the avatar's right hand. In the sample, the calculations to create the world space transform are done in the BonesToWorldSpace method. The method takes three parameters—an AvatarRenderer, an AvatarAnimation, and a List<Matrix> that will hold the results. You can then look up a specific bone in the resulting list by using the AvatarBone enum value for a bone as an offset into the list. An example of how to find a particular bone is shown in the DrawBaseballBat method in the sample.

To calculate bone transforms in world space, a few pieces of information are needed:

AvatarRenderer.World
The avatar renderer's world transform is needed to find where the avatar has been transformed in the world. This transform is in world space.
AvatarAnimation.BoneTransforms
The avatar animation bone transforms are a list of transforms for each bone. The avatar render uses these transforms to draw the avatar that is using the animation. Each transform is relative to the bind pose transform for the bone in the list.
AvatarRenderer.ParentBones
A list that contains the parent bone index for each bone. The root bone has a parent index of −1 since it does not have a parent.

Since each bone is relative to its parent bone, you need to first calculate the world space transform of the bone's parent. This turns out to be simple since the list of transforms is sorted by depth, so the first item is the root, followed by its children, and so on. This allows you to process the list sequentially. You can look up the parent's world space transform by using the AvatarRenderer.ParentBones property as an index value into the final list. This means that the root bone needs a special case, and the AvatarRenderer.World transform is used.

The next step is to multiply the bones animation transform from the AvatarAnimation.BoneTransforms property with the bones bind pose transform from the AvatarRenderer.BindPose property.

The final step is to multiply that result with the result from the bones' parent. Again, you can look up that parent's value by using the AvatarRenderer.ParentBones property.

Now that you've created a list of bone transforms in world space, you can look up a specific bone by using the AvatarBone enum value as an offset into the list. You then use this final matrix as the world matrix for the object you wish to draw. In this sample, you use a baseball bat and select the AvatarBone.SpecialRight bone that is near the avatar's right hand. You also apply a slight translation and rotation to make the bat fit slightly better to the hand.

Extending the Sample

When playing the animations, notice that the avatars fingers on the right hand animate and do not grip the baseball bat. One way to make it appear more realistic would be to have the avatar grip the bat. You accomplish this by copying the animation bone transforms into a separate list and then overriding the transforms for the fingers on the right hand. You would need to supply transforms that would cause each of the finger bones to rotate slightly to grip the bat. Then use this new overridden list with the AvatarRenderer.Draw method to draw the avatar.