Clone wiki

sig / Skeletons and Motions

The Kinematics module of SIG includes several tools for working with skeletons and motions. The classes in this module start with Kn. These classes are compiled in the independent library libsigkin which has to be linked with your application.

Main Classes

The main classes in the Kinematics module are listed below:

  • KnSkeleton is the main class for working with hierarchical objects. It maintains an array of joints, each joint being represented with KnJoint which handles different joint parameterizations with range limits and automatic conversions between parameterizations. Skeletons can be loaded from the popular .bvh format, or from SIG's .s skeleton format. Joints can be efficiently retrieved by name using a built-in hash table, can be listed using the array of joints, or traversed recursively using the parent-child relationship in the hierarchy tree. The header file kn_skeleton.h provides details of additional supported functionality such as connecting to collision detectors, storing pre-defined postures to be applied to the skeleton, attaching user data, and handling rigid body parts or skin deformations.

  • KnMotion is the main class for working with motions defined as series of frames. It maintains an array of postures representing frames, each frame being a shared KnPosture which handles joint values to be sent to attached joints. Motions can be loaded from the popular .bvh format, or from SIG's .m motion definition format. After a motion is created or loaded, motions should be first connected to a skeleton or posture before applying frames to the connected object. Frames can be applied by frame index (using apply_frame()), or by keyframe interpolation (using apply()) where the desired keytime is given and used to interpolate the adjacent frames to the given keytime. Motions can therefore be defined for keyframe interpolation or for constant-rate motion capture representation. Motion connection is made by joint name, leading to a very flexible mechanism to map motions to different skeletons and postures for interpolation and blending operations.

  • KnPosture is the class that handles values to be sent to skeleton joints or other postures. It needs to be first connected to another posture or to a skeleton, and then its values can be applied to the connected object. Postures also include a list of channels which specify joint names and degrees of freedom (DOFs) of each stored value. Channels provide the needed information for connecting to any given skeletons, and only matched channels are actually connected. Once connected a posture remains connected with direct pointers to the connect object for fast transfer of posture values. The header file kn_motion.h provides details of additional supported functionality such as maintaining key positions for a posture distance metric computation, generation of random values, and posture interpolation.

  • KnIk implements a fast analytical IK solver for 7-DOF linkages. It requires specific parameterizations in the target linkage in order to support handling range limits and collision avoidance techniques, as described in [K08]. The different classes starting with KnIk provide different ways for applying the IK solver to hierarchies and to connect it with scene graph manipulators.

  • KnCtScheduler provides functionality to declare multiple motions, in the form of generic controllers, in a timeline including multiple activation times and smooth transition blending. It is a good example of how several operations with motions and skeletons can be implemented. Related classes are KnController and classes starting with KnCt.


Skeleton files are text files simple to be written. Example of a .s file describing a simple arm structure:

root joint1
{ visgeo "link.m"
  colgeo "link.m"
  modelrot 0 0 1 -90 # to orient the link in x direction
  channel ZRot 0 lim -180 180

  joint joint2
   { offset 8 0 0
     visgeo "link.m"
     colgeo "link.m"
     modelrot 0 0 1 -90 # to orient the link in x direction
     channel ZRot 0 lim -180 180

     joint wrist
      { offset 8 0 0
        channel ZRot 0 lim -180 180

        joint hand
         { visgeo "hand.m"
           colgeo "hand.m"
           modelrot 0 0 1 -90 # to orient the hand in x direction
           channel ZRot 0 lim 0 0

Below are examples demonstrating operations with skeleton joints involving transformations in local and global frames:

   KnJoint* j1 = sk->joint("joint1");
   KnJoint* j2 = sk->joint("joint2");
   KnJoint* w = sk->joint("wrist");
   KnJoint* h = sk->joint("hand");

   // Apply local rotations around Z axis:
   const int Z=2;

   // Get local transformations in joint frame:
   GsMat L1 = j1->lmat();
   GsMat L2 = j2->lmat();
   GsMat W = w->lmat();
   GsMat H = h->lmat();

   // Display matrices for inspection:
   gsout<<"Link 1 Local Transformation:\n"<<L1<<gsnl;
   gsout<<"Link 2 Local Transformation:\n"<<L2<<gsnl;
   gsout<<"Wrist Local Transformation:\n"<<W<<gsnl;
   gsout<<"Hand Local Transformation:\n"<<H<<gsnl;

   // Compute global matrix of hand joint:
   GsMat Hfk = L1 * L2 * W * H;
   gsout<<"Hand Global Frame by FK: \n"<<Hfk<<gsnl;

   // We can also ask the global matrix to the skeleton:
   GsMat Hg = h->gmat();
   gsout<<"Hand Global Frame: \n"<<Hg<<gsnl;
   gsout<<"Hand Center in Global Coordinates: \n"<< GsVec(Hg[3],Hg[7],Hg[11]) << gsnl;