Use fully baked skeletal animation data to reduce the processor load for animation evaluation compared to frame format.
However, there are major functional limitations, and the data size is larger.
The fully baked format outputs the frame format data using the model coordinate system. (Frame format usually uses the bone coordinate system.)
The skeletal structure is calculated on binary output so the skeleton does not need updating at runtime, reducing the processing load.
Use this mode as follows.
--use_full_baked_anim option to the command-line version of CreativeStudio to output the data.SetFullBakedAnimEnabled function to enable fully-baked output.
Use the IsFullBakedAnim function to check that the animation is fully baked.
Note that fully baked animations are subject to the following functional restrictions, and are only suited to simple playback.
Reset on bound poses..cskla file.This outputs an animation of all bone and SRT elements, resulting in larger file sizes compared to regular frame format.
There are multiple skeletal animation formats.
Each has different characteristics, making each better suited to specific uses.
| Type | Animation Evaluation | Binary Size | Comments |
|---|---|---|---|
| Key Frame Animation | - | - | Key frame animation as the standard. |
| Frame-format Animation | High speed | Bigger file size | Playback may be choppy for low numbers of frames. See the FAQ for details. |
| Fully Baked Animation | Faster still than frame format | Bigger file sizes than frame format | Various restrictions. See Fully Baked Format Description for details. |
Sharing skeletons when the bone configuration is the same and applying animations to shared skeletons can be very efficient. For details on sharing skeletons, see Sharing skeletons. After sharing, be sure to bind the animation to any one SkeletalModel.
Information on how to do this when bone configurations differ is scheduled as a future addition.
Use a cache to reduce the processing load when applying animation results to more than one model.
Enable cache use setting true for AllocCache using options available when creating AnimEvaluator.
If the cache is enabled, call the GetResult function to get cached results. Call the UpdateCache function to update the cache.
Note that enabling cache use entails some overhead due to an increase in memory copying.
Be sure to disable cache use if it is not required, such as when there is only one model or when frame format data is being used.
To configure separate animations, register multiple animations for a single model such that animated elements do not overlap.
For example, you can manage animations of the upper and lower body separately, or split the ambient color and diffuse color of a material into separate animations.
Implement this using code like the following.
// You can configure several animations when creating models from resources.
nw::gfx::SceneBuilder builder;
nw::gfx::SkeletalModel* model =
builder.Resource(resource)
.MaxAnimObjectPerGroup(2) // This line sets the maximum number of animations per model.
.CreateObject(&allocator, &deviceAllocator)
// evaluator0 and evaluator1 represent the AnimEvaluator for the upper and lower body, respectively.
// Set two animations for the model.
model->SetSkeletalAnimObject(evaluator0, 0);
model->SetSkeletalAnimObject(evaluator1, 1);
For details, see PartialAnimationDemo.
In AnimInterpolator version 1.0.1 and earlier, members that are not animated are skipped during the blending process. Meanwhile, the current implementation uses the OriginalValue (the status when the model was loaded) in blend calculations for members without animations. Members without animations are also included when normalizing weights.
In version 1.01 and earlier, weights are normalized for all members every frame. The current implementation only does this when necessary in the aim of improving performance.
Upper body animation: A, B (neither includes lower body animation) Lower body animation: C, D (neither includes upper body animation)
Blending all four of these animations in version 1.01 or earlier would produce the ultimate result of blending A and B for the upper body and blending C and D for the lower body. (Note that this behavior can be restored in the current version by enabling IgnoreNoAnimMember.)
To get similar results using the current implementation, blend A and B using one interpolator and blend C and D with a different interpolator. Register two Interpolator objects for target models when performing partial animations to achieve the same results as for previous versions.
// The following represents the above description in code form.
AnimEvaluator* evaluator_lower_0; // Lower body animation:1
AnimEvaluator* evaluator_lower_1; // Lower body animation: 2
AnimEvaluator* evaluator_upper_0; // Upper body animation 1
AnimEvaluator* evaluator_upper_1; // Upper Body Animation 2
// Code in version 1.0.1 and earlier
{
AnimInterpolator* blender = AnimIntrerpolator::Builder()
.MaxAnimObjects(4)
.Create(&allocator);
blender->Bind(animGroup);
// In the old code, members that were not animated were skipped during blending, so...
// Animations for the upper and lower body are blended separately.
blender->AddAnimObject(evaluator_lower_0);
blender->AddAnimObject(evaluator_lower_1);
blender->AddAnimObject(evaluator_upper_0);
blender->AddAnimObject(evaluator_upper_1);
blender->SetWeight(0, 0.5f);
blender->SetWeight(1, 0.5f);
blender->SetWeight(2, 0.1f);
blender->SetWeight(3, 0.9f);
// Register AnimObject with the model.
model->SetSkeletalAnimObject(blender);
}
// Current code
{
// Members without animations are blended using OriginalValue in new code.
// Consequently, provide separate blenders for the upper and lower bodies.
AnimInterpolator* blender_lower = AnimInterpolator::Builder()
.MaxAnimObject(2)
.Create(&allocator);
AnimInterpolator* blender_upper = AnimInterpolator::Builder()
.MaxAnimObject(2)
.Create(&allocator);
blender_lower->AddAnimObject(evaluator_lower_0);
blender_lower->AddAnimObject(evaluator_lower_1);
blender_upper->AddAnimObject(evaluator_upper_0);
blender_upper->AddAnimObject(evaluator_upper_1);
blender_lower->SetWeight(0, 0.5f);
blender_lower->SetWeight(1, 0.5f);
blender_upper->SetWeight(0, 0.1f);
blender_upper->SetWeight(1, 0.9f);
// Set so that multiple AnimObject instances can be registered per model.
// Apply the blend results for the upper and lower body to each model using partial animation.
model->SetAnimObject(blender_lower, 0);
model->SetAnimObject(blender_upper, 1);
}
CONFIDENTIAL