Reader small image

You're reading from  C++ Game Animation Programming - Second Edition

Product typeBook
Published inDec 2023
Reading LevelN/a
PublisherPackt
ISBN-139781803246529
Edition2nd Edition
Languages
Tools
Concepts
Right arrow
Authors (2):
Michael Dunsky
Michael Dunsky
author image
Michael Dunsky

Michael Dunsky is an educated electronics technician, game developer, and console porting programmer with more than 20 years of programming experience. He started at the age of 14 with BASIC, adding on his way Assembly language, C, C++, Java, Python, VHDL, OpenGL, GLSL, and Vulkan to his portfolio. During his career, he also gained extensive knowledge in virtual machines, server operation, infrastructure automation, and other DevOps topics. Michael holds a Master of Science degree in Computer Science from the FernUniversität in Hagen, focused on computer graphics, parallel programming and software systems.
Read more about Michael Dunsky

Gabor Szauer
Gabor Szauer
author image
Gabor Szauer

Gabor Szauer has been making games since 2010. He graduated from Full Sail University in 2010 with a bachelor's degree in game development. Gabor maintains an active Twitter presence, and maintains a programming-oriented game development blog. Gabor's previously published books are Game Physics Programming Cookbook and Lua Quick Start Guide, both published by Packt.
Read more about Gabor Szauer

View More author details
Right arrow

11

Blending between Animations

Welcome to Chapter 11! In the previous chapter, we took our first steps in character animations. We explored the way animations are stored in the glTF file format, extracted the data, and were finally able to watch our character become animated.

In this chapter, we push the envelope even further. We will start with an overview of animation blending, and dive into the first part of character animations: blending between the binding pose and any animation clip. You will learn how to extend the current code to change the blending by adjusting a slider in the user interface.

Next, we will upgrade our work to feature crossfading between two animations. Crossfading is like simple blending, but instead of blending from the binding pose as the starting point, we play an animation clip and blend it into another animation clip.

At the end of the chapter, we will look at additive animation blending. Additive blending is different from simple blending...

Technical requirements

To follow along with this chapter, you will need the OpenGL and Vulkan renderer code from Chapter 10.

Let us start with a brief overview of the types of animation blending.

Does it blend?

In Chapter 10, we did our animations by simply overwriting the translation, rotation, and scale node properties with the values taken from the channels and samplers entries. If we did not hit the exact time of one of the time points that are stored in the mTimings vector of the GltfAnimationChannel class, the values were interpolated using linear, spherical linear, or spline interpolation. But we never had the chance to choose any option other than the animation clip.

In animation blending, we can adjust the extent of the node property changes. The adjustment can be made between the binding pose and any animation clip, between two different animation clips, and be limited to parts of the character model.

As we will cover all three variants, let us take a quick look at these animation blending types and their characteristics.

Fading animation clips in and out

In the simplest form, animation blending changes only the amount of the node property changes. We...

Blending between the binding pose and animation clip

To blend from the binding pose to an animation clip, we add three new variables for the translation, scale, and rotation to every node. While the original variables store the node properties for the binding pose, the new variables will be used to save the node property changes that occur during the animation clips. By interpolating the translation, scale, and rotation values between the binding pose and the animation clip, we can control the amount of influence of the animation clip over the binding pose.

Let’s start by adding some new variables to the node class.

Enhancing the node class

The data type of the new variables must be the same as for the original values, so we just add three new variables with the prefix Blend as new private data members of the GltfNode class to the GltfNode.h file in the model folder:

    glm::vec3 mBlendScale = glm::vec3(1.0f);
    glm::vec3...

Crossfading animations

While the default animation blending uses the binding position with the joint weights as the starting point, crossfading interpolates between two animation clips. We could use the same animation clip as both the source and destination, but this would just play the animation, regardless of the position of the crossfading slider.

We will enhance the GltfModel class to store the values for two animation clips, instead of only the binding pose and one animation clip. For the renderer, new shared variables are needed, containing the second clip name and the percentage of blending between the two clips. The user interface must also reflect the new blending mode and new controls, like the selected destination clip, or a slider to adjust the percentage of the blending between the two clips. As the first step, we’ll update the model class.

Upgrading the model classes

To set the starting point of the glTF model to an animation, we will abuse the default...

How to do additive blending

The basic principle of additive animation blending has already been outlined in the Does it blend? section. We must split our model into two distinct parts and animate both parts using different animation clips. Let’s see how.

Splitting the node skeleton – part I

The first change is for convenience, as it allows us to print the name of the current node in the user interface. Add the following public method to the GltfNode.h file in the model folder:

std::string getNodeName();

In the implementation in the GltfNode.cpp file, also in the model folder, we return the saved node name:

std::string GltfNode::getNodeName() {
  return mNodeName;
}

Splitting the model will be done in the GltfModel class. We add the two public methods, setSkeletonSplitNode() and getNodeName(), to the GltfModel.h file in the model folder:

    void setSkeletonSplitNode(int nodeNum);
    std::string getNodeName...

Summary

In this chapter, we moved from pure animation replays to animation blending.

We started with a brief overview of the three animation blending types that are part of this chapter. Then, we added simple blending between the binding pose and one animation clip, and worked on an example of cross-blending between two animation clips.

As the last step, we added the code for additive animation blending. Additive blending works differently compared to the other two blending types, and requires adding the ability to split the skeleton tree into two parts.

In the next chapter, we switch the topic entirely, and add new control element types to the UserInterface class. Some of the new elements will help us to clean up the user interface, while others will allow us to show more information about the internals of the renderer.

Practical sessions

You may try out the following ideas to explore more features of animation blending:

  • Update the GltfNode class to include another set of properties storing the translation, rotation, and scaling values, and use them to apply cross-blending to two animations. Adding a third property set should enable you to get rid of the model reset in the renderer class, which is currently required after changing the blending type to reload the original data from the model file.
  • Blend between three different animation clips. This technique is perfect for a transition between the idle animation clip to the running clip and back, using the walking animation as the connection between the two movements.
  • Add a speed adjustment for clips of different lengths. In the current code, the time for the second animation clip is stretched or compressed to match the length of the first clip, resulting in faster or slower playback. Adjusting the playback speed in the opposite direction...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
C++ Game Animation Programming - Second Edition
Published in: Dec 2023Publisher: PacktISBN-13: 9781803246529
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $19.99/month. Cancel anytime

Authors (2)

author image
Michael Dunsky

Michael Dunsky is an educated electronics technician, game developer, and console porting programmer with more than 20 years of programming experience. He started at the age of 14 with BASIC, adding on his way Assembly language, C, C++, Java, Python, VHDL, OpenGL, GLSL, and Vulkan to his portfolio. During his career, he also gained extensive knowledge in virtual machines, server operation, infrastructure automation, and other DevOps topics. Michael holds a Master of Science degree in Computer Science from the FernUniversität in Hagen, focused on computer graphics, parallel programming and software systems.
Read more about Michael Dunsky

author image
Gabor Szauer

Gabor Szauer has been making games since 2010. He graduated from Full Sail University in 2010 with a bachelor's degree in game development. Gabor maintains an active Twitter presence, and maintains a programming-oriented game development blog. Gabor's previously published books are Game Physics Programming Cookbook and Lua Quick Start Guide, both published by Packt.
Read more about Gabor Szauer