Skeletal Animation (Advanced Methods in Computer Graphics) Part 3

Transformation Blending

If every vertex is attached to only a single bone, then transformations applied to the bones may cause mesh surfaces to interpenetrate at a joint (Fig. 4.12a, b).

Figure 4.12b also shows how large flat surface patches can appear at a joint when two adjacent vertices move away from each other because of a rotational transformation. It is intuitive to transform vertices in the neighbourhood of a joint using a combination of bone matrices which influence that joint. If i and j are two bones that influence a joint, then a vertex V in the vicinity of the joint may be transformed using a weighted combination of the bone’s matrices Bi and Bj. The weights wi and Wj are usually selected based on the relative distances of the vertex from the bones (Fig. 4.13). The final transformed point W (Fig. 4.12c) is obtained as

tmpc2f9-157_thumb[2]_thumb

 

(a) A joint formed by two bones, and the attached mesh. (b) Interpenetration of mesh surfaces at a joint. (c) Mesh transformation using a combination of two bone matrices


Fig. 4.12 (a) A joint formed by two bones, and the attached mesh. (b) Interpenetration of mesh surfaces at a joint. (c) Mesh transformation using a combination of two bone matrices

Multiple weights associated with vertices for combining bone matrices

Fig. 4.13 Multiple weights associated with vertices for combining bone matrices

We also require the weights to satisfy the condition w; + Wj = 1. A sample distribution of weights for mesh vertices of the joint in Fig. 4.12a is shown above (Fig. 4.13).

In general, if n bones with indices 1,2, …, n meet at a joint, the vertices surrounding the joint may be transformed using a matrix

tmpc2f9-160_thumb[2]_thumb

The method outlined above is called transformation blending, and it usually produces smooth mesh deformations near joints. However when the angle of rotation of a bone is very large compared to its parent, the averaging scheme in Eq. 4.11 can produce two types of undesirable artefacts shown in Fig. 4.14. The first one is called a collapsing elbow effect, which appears when the angle between the axes of two adjacent bones becomes small. In this situation, vertex points on the inner edge of the mesh that are located near the joint move towards the centre. The second type of artefact is called the candy-wrapper effect, where one of the bones is twisted by 180° about its axis. In this case, vertices with nearly equal weights get transformed to closely located points near the joint.

 (a) Collapsing elbow effect. (b) Candy-wrapper effect

Fig. 4.14 (a) Collapsing elbow effect. (b) Candy-wrapper effect

Keyframe Animation

The animation of an articulated character model is usually done by specifying a set of keyframes that contain the information about the required joint transformation parameters at certain discrete points in time. Keyframes are generally predefined by an artist or an animator who can clearly specify the motion an object is required to produce. The joint angles for a character model at various instances in an animation sequence can also be obtained from motion capture systems. Here, the actions performed by a human actor are captured through the placement of markers near each joint of the body, and their recorded positions used to compute joint angles.

A keyframe is essentially a time stamp of important transformation parameters and, optionally, other attributes such as colour, transparency etc. that are needed to render one frame of an animation sequence. As an example, consider a keyframe animation of the model of a stick figure shown in Fig. 4.15a.

(a) Model of a stick figure and (b) the joint chains used for its animation. The hierarchical structure of links consists of five branches (chains), and 14 internal nodes. A leaf node is indicated by a blank square

Fig. 4.15 (a) Model of a stick figure and (b) the joint chains used for its animation. The hierarchical structure of links consists of five branches (chains), and 14 internal nodes. A leaf node is indicated by a blank square

The four primary keyframes used for generating a walk sequence of the stick figure. The graphs show the values of some of the joint angles, and a linear interpolation between the values is indicated by dotted lines

Fig. 4.16 The four primary keyframes used for generating a walk sequence of the stick figure. The graphs show the values of some of the joint angles, and a linear interpolation between the values is indicated by dotted lines

This model has five joint chains, and a total of 14 joints (Fig. 4.15b). A single configuration or "pose” of the model is therefore given by 14 joint angles 60, 61, …, 613, and the position (x0, y0, z0) of the root joint. A joint rotation that moves a link forward (towards + z) is considered as positive. For example, the elbow joints are constrained to rotate the arm only forward, by assigning only positive values for 64 and 65. Similarly the knee joint angles (610, 611) are always assigned a negative value. An alternative definition for these joint angles can be obtained by viewing them as rotations about the x-axis. In this case, the angles at shoulders and elbows will have negative values, and the angles at the knees will have positive values.

For a simple walk sequence for the stick figure, four key-frames are defined as shown in Fig. 4.16. These are the primary postures from which the intermediate motion can be generated by linear interpolation. In our example, movements of the neck, shoulder and wrists are neglected, and hence values of only ten joint angles are specified for each keyframe. More complex and realistic movements such as running, jumping or performing somersaults can be produced by creating a larger number of keyframes using motion capture systems.

Commonly used interpolation methods in keyframe animation

Fig. 4.17 Commonly used interpolation methods in keyframe animation

The “in-between” frames of an animation sequence are generated by interpolating keyframe values using either step, linear or spline functions. A step function uses the previous keyframe values for all subsequent frames until another keyframe is encountered (Fig. 4.17a). A linear interpolation produces points along line segments connecting two consecutive keyframes (Fig. 4.17b). If k1 denotes a parameter in a keyframe at time t1, and k2 denotes the value of the same parameter in the next keyframe at time t2, the value k for an in-between frame at time t is given by

tmpc2f9-165_thumb[2]_thumb

or equivalently,

tmpc2f9-166_thumb[2]_thumb

where

tmpc2f9-167_thumb[2]_thumb

For smoother motion interpolation, keyframe values are connected using piecewise cubic splines (Fig. 4.17c). Catmull-Rom splines are commonly used for this purpose, as they have properties of both C° and C1 continuity between consecutive spline segments. Please refer to Chap. 7 (Sects. 7.2 and 7.5) for more information on Catmull-Rom and other types of splines that are useful for generating approximating curves and surfaces.

Sample Implementation of Vertex Skinning

In Sect. 3.5 we discussed the implementation of a scene graph class. For vertex skinning, we will use a highly simplified model where the information attached to each node is appended with a vertex index range given by the first and the last indices of the range. In this model, there is no need for an object node, and the vertices are processed at group nodes only. Listing 4.1 gives the class definition for a skeleton node.Just like a scene graph node, a skeleton node also stores transformation parameters and a list of pointers to its child nodes.

Skeleton Node

The primary function of the SkeletonNode is to provide a convenient framework for representing the bone hierarchy and also to transform the vertex list of a mesh model using joint angles specified for each bone. The two functions preprocessPhase() and animationPhase() both initiate a recursive traversal of the tree to transform entries in the vertex lists as shown in Fig. 4.11.

It is useful to have a Skeleton class with functions to load a skeleton definition and to define joint angles for bones during animation (Listing 4.2). These two functions provide the main interface between the classes and the user application. A Skeleton object represents the whole skeleton of a mesh model consisting of several bones (skeleton nodes).

The contents of the skeleton definition file are organized as shown in Fig. 4.18. The loadSkeleton() function reads in the parameters and builds the hierarchical structure. The reference to the root node is available to the application via the function getRoot().

Next post:

Previous post: