Tip:
Highlight text to annotate it
X
HumanIK is designed to expand a character's existing set of motions at runtime
by dynamically controlling the character's skeleton using full-body IK and retargeting solvers.
Before you can access the HumanIK libraries in your game engine, you first need to integrate HumanIK into the engine.
Once this is done, you're ready to use HumanIK programmatically.
In this movie, we'll cover the first phase required to use HumanIK at runtime: Initialization.
The initialization phase sets up the character you intend to control with HumanIK. There are four basic steps:
1. Creating an HIKCharacter object to represent the HumanIK-enabled character, also known as the characterization process.
2. Creating an HIKCharacterState object,
which stores your character's pose based on the translation and rotation of each joint in its HumanIK skeletal hierarchy.
3. Creating an HIKPropertySetState object to configure how the HumanIK solvers will handle your character.
4. Creating an HIKEffectorSetState object,
which sets the target points for each of the character's body parts, as well as a set of corresponding constraints.
Let's go over each step to better understand how they work together.
First, you must create an HIKCharacter object.
Each instance of the HIKCharacter class represents a HumanIK-enabled character in the code.
The class itself contains everything HumanIK needs to "understand" your character's skeleton structure and geometry
so that it can be controlled at runtime.
You create the HIKCharacter through a process called "characterization", which defines the following:
A mapping between each joint in your character's skeleton and its corresponding Node in the HumanIK bio-mechanical model.
And the translation, rotation, and scale values for each joint that defines your character's default pose, also referred to as a "T-stance".
This means that whether your character has a standard humanoid skeleton structure or exaggerated proportions,
the HIKCharacter stores this data and passes it to the HumanIK solvers
so it can control your character regardless of these differences.
In addition, the HIKCharacter object can include other optional values like degrees of freedom and parent offsets for each joint.
We'll skip these for this basic initialization. Since they are not mandatory, omitting them will not affect the final result.
In order to create an HIKCharacter, you must first create an instance of the HIKCharacterDefinition class.
The HIKCharacterDefinition acts as a blueprint that identifies a set of HIK Node IDs corresponding to the joints used in your character.
Those HumanIK Node IDs are stored in a "mUsedNodes" array for easy access.
The HIKCharacterDefinition must contain at least the fifteen Nodes required by HumanIK.
These required Nodes correspond to the main joints in your character's skeleton,
and are essential to complete the characterization.
The other Nodes in the HumanIK hierarchy, such as fingers, toes, and roll Nodes,
are optional and do not affect the characterization to the same degree.
For example, roll Nodes provide better twisting deformation in your character's arms and legs,
but are not strictly necessary to build a working skeleton.
In some cases you may notice some differences in naming convention between your skeleton joints
and the corresponding HumanIK Node IDs.
This is normal because the HumanIK API names each Node based on the joint it represents,
as opposed to the bone that extends from that joint.
To create an HIKCharacter based on the HIKCharacterDefinition,
you need to call the HIKCharacterCreate function with the following arguments:
A pointer to HIKCharacterDefinition.
A pointer to the callback function that will allocate memory for the HIKCharacter.
And the customer identification string and customer key values, both included in your HumanIK runtime license file.
Note that if you already copied these license values in the autodeskmwkey.h file
when you first integrated HumanIK into your game engine,
You can simply include that file and use the pre-defined values AutodeskCustomerString and AutodeskCustomerKey.
We now have an HIKCharacter object containing all the HumanIK Nodes that we'll use to control our character.
However, we still need to set translation, rotation, and scale values for each of these joints in order to match the required T-stance.
To set default transform values,
call the HIKSetCharacterizeNodeStateTQSfv function for each character Node.
This function requires three separate arrays of four floating-point numbers as arguments,
representing the translation, quaternion rotation, and scale values of the current Node in global space.
Alternatively, you can call the HIKSetCharacterizeNodeStatefv function that uses a 4x4 transform matrix instead of arrays.
Finally, call the HIKCharacterizeGeometry function to complete the characterization.
Your HIKCharacter is now ready for the next steps in the initialization process.
Depending on your production pipeline, the characterization we just covered programmatically can also be done visually by an artist.
For example, using Maya, Softimage, or the standalone Characterization Tool available with the HumanIK SDK,
an artist can pre-generate a characterization that is ready for you to use.
This characterization is saved as a binary .hikc file containing the information needed to create a new HIKCharacter object.
In addition, a .bones.xml file is created,
which contains the bone correspondence between each character joint and the matching HumanIK Node.
To create an HIKCharacter from the .hikc characterization file,
you must first load it into memory using the file management interface of your project.
Then create a new instance of the HIKCharacterDefinition class and call the HIKReadFromStream function to create a new HIKCharacter.
This function requires most of the same arguments as the HIKCharacterCreateDefinition function we've just seen earlier.
These arguments include pointers to the HIKCharacterDefinition, memory allocation functions, and your license key.
Finally, close the file stream.
You now have an HIKCharacter generated from an external characterization file.
The second step in the initialization process is to create an HIKCharacterState object.
The HIKCharacterState contains the translation and rotation matrix for each of your character's Nodes.
Think of it as taking a snapshot of your character's pose at the current frame.
The HumanIK solvers actually use the HIKCharacterState twice at runtime:
Once as input to provide a starting pose for the IK calculations,
And again as output when the solvers complete their calculations.
We'll cover this more extensively in the next movies.
To create the HIKCharacterState, call the HIKChararacterStateCreate function
with pointers to your HIKCharacter and to a memory allocation callback function, as arguments.
Next, you need to create an HIKPropertySetState object to define a set of optional attributes
related to how the HIK solvers handle your HIKCharacter.
This includes properties such as floor contacts, joint mirroring options, spine stiffness, and so on.
Call the HIKPropertySetStateCreate function to create it, with only a memory allocation callback function as an argument.
Note that this solver property object does not directly service a specific HIKCharacter or HIKCharacterDefinition.
This is because HIKPropertySetState contains the same properties for all HIKCharacter instances.
Finally, create an HIKEffectorSetState object to store transform and constraints information related to the Effectors.
Effectors are essentially target points in space for each of your character's body parts.
At every frame, the HumanIK solver looks at where these Effectors are, and then controls the character's body parts to match them.
The HIKEffectorSetState object contains the Effectors' position and rotation values,
as well as their set of Reach, Pull, and Resist constraints.
These constraints control how strongly the final generated pose should attempt to reach each Effector.
The HIKEffectorSetState also defines which body part the HumanIK solver chooses to control.
Call the HIKEffectorSetStateCreate function to create it, with only a memory allocation callback function as an argument.
You've now fully initialized your character for HumanIK.
Repeat this process once at runtime for every character you plan to control with the HIK solvers.
Also, you'll probably want to maintain this set of HumanIK objects within class members of your game character class,
so that they can be easily accessed when evaluating that character's pose at each frame.
In the next movie, we'll go over the HIK solving process that updates your character's skeleton at runtime.