Skeleton Mapping |
DigitalRune Animation supports skeleton mapping which can be used to transfer an animation from one skeleton to another skeleton with a different structure.
This topic contains the following sections:
Skeleton mapping can be used to transfer skeletal poses from one skeleton to another skeleton with a different topology (different number of bones, different bone poses, rotated bones, etc.). Skeleton mapping can be used for:
The SkeletonMapper establishes the relations between two skeletons using a collection of BoneMappers. The SkeletonMapper allows to transfer poses in both directions.
DigitalRune Animation contains several predefined bone mapper classes:
Without the bone mappers, the skeleton mapper does nothing. Bone mappers must be configured manually. Defining the right bone mappers is not trivial if the skeletons are very different. The skeleton mapping sample in the CharacterAnimationSample contains tips that help to set up a skeleton mapping between two skeletons.
See the class SkeletonMapper, the class BoneMapper, and derived bone mappers for more information.
Motion retargeting (or more precise: animation retargeting) is the process of transferring the animations of one character to another character with a different skeleton topology. In the following video, the walk animation of the Dude model (left) is applied to the Marine model (right).
At the first look the models seem similar, but a look at skeletal structure reveals a number of differences:
(The orange lines represent bones and the red-green-blue tripods indicate bone spaces.)
Motion retargeting is done using the SkeletonMapper. Following example code defines the mappings between the models in the video:
_mapper = new SkeletonMapper(_dudeSkeletonPose, _marineSkeletonPose); // Pelvis _mapper.BoneMappers.Add(new DirectBoneMapper(1, 1) { MapTranslations=true }); // Spine _mapper.BoneMappers.Add(new ChainBoneMapper(3, 6, 2, 3)); // Clavicle _mapper.BoneMappers.Add(new DirectBoneMapper(12, 6) { MapTranslations=false }); _mapper.BoneMappers.Add(new DirectBoneMapper(31, 12) { MapTranslations=false }); // Left leg _mapper.BoneMappers.Add(new ChainBoneMapper(50, 51, 16, 17)); _mapper.BoneMappers.Add(new ChainBoneMapper(51, 52, 17, 18)); _mapper.BoneMappers.Add(new DirectBoneMapper(52, 18) { MapTranslations=false }); // Right leg _mapper.BoneMappers.Add(new ChainBoneMapper(54, 55, 21, 22)); _mapper.BoneMappers.Add(new ChainBoneMapper(55, 56, 22, 23)); _mapper.BoneMappers.Add(new DirectBoneMapper(56, 23) { MapTranslations=false }); // Left arm _mapper.BoneMappers.Add(new ChainBoneMapper(13, 14, 7, 8)); _mapper.BoneMappers.Add(new ChainBoneMapper(14, 15, 8, 9)); _mapper.BoneMappers.Add(new DirectBoneMapper(15, 9) { MapTranslations=false }); // Right arm _mapper.BoneMappers.Add(new ChainBoneMapper(32, 33, 12, 13)); _mapper.BoneMappers.Add(new ChainBoneMapper(33, 34, 13, 14)); _mapper.BoneMappers.Add(new DirectBoneMapper(34, 14) { MapTranslations=false }); // Neck, head _mapper.BoneMappers.Add(new ChainBoneMapper(6, 7, 3, 4)); _mapper.BoneMappers.Add(new DirectBoneMapper(7, 4) { MapTranslations=false });
The numbers in brackets are simply bone indices. Once the mapping is initialized, any animations running on one model can be copied to the other model by calling:
_skeletonMapper.MapAToB();
or
_skeletonMapper.MapBToA();
These methods transfer the current pose and must be called each frame.
Another application of the skeleton mapper is ragdoll mapping:
Imagine a character with 60+ bones. Creating a ragdoll with 60+ rigid bodies (one per bone) is a bad idea performance-wise. Ragdolls should have a low number of bodies; for example, 15 bodies (or less). In this scenario there are two skeleton representations for one model. A 60 bone, high-detail skeleton is used to animate the visual model. A 15 bone, low-detail skeleton represents the ragdoll. We can create a skeleton mapper that maps between both skeletons. The skeleton mapper can transfer key frame animations from the high-detail skeleton to the ragdoll, or ragdoll poses to the visual character.
Important |
---|
It is not always required to use a skeleton mapper to create a low-detail ragdoll for a high-detail skeleton. The ragdoll samples of DigitalRune Animation (see Samples) show that it is possible to create a ragdoll for the high-detail skeleton directly by simply ignoring some bones. Both approaches have their pros and cons. For beginners and simple scenarios (like in the samples), we recommend not using the skeleton mapper. |
If you perform motion retargeting at runtime and run into performance issues, then it is better to use the skeleton mapper in the preprocessing stage: Retarget the animation once and store the retargeted animation as a new key frame animation.
If the mapped skeletons are very different, the mapped animation is not optimal. In the video above, you can see that the feet of the Marine model are tilted, and there are other minor issues. The mapping process is not perfect.
If the standard BoneMappers don’t do a good job for a model, then you can create custom bone mapper types or extend the existing classes.