Motion Generation: The Puppet Maker

 

    The puppet Maker is a motion generation program based loosely off Ken Perlin's paper Real-Time Responsive Animation with Personality.  The program allows you to queue up a series of motions either with or without one dimensional Perlin noise added to the joints.  Motion queues can be written out in BVH format.  The original intention of this program was to animate background characters in the animation Dancin' Fool.

Program Usage:

  1. Motions are added to the motion queue by clicking the motion buttons along the right hand side of the window. Spherical linear interpolation of the quaternion joint rotations is used to move into the first motion and to blend between different motions but if a motion is followed by another instance of its self there is not interpolation period.  For example if the queue contains "rhumba clap" there will be a period of interpolation between the rhumba and the clap motions, however if the queue is "clap clap" there will be no period of interpolation between the clap motions.

  2. The clear button erases the motion queue.

  3. When the add noise button is on any motions added to the queue will have a one dimensional Perlin noise added to all the joints except for the root.  This noise is at most a 10 degrees in a random direction.

  4. The file menu allows the user to save the current motion queue to a file in BVH format.

 

How it works:

The skeleton used in this program contains 20 joint with the hierarchy constructed like this:

Root->addChild(Waist);                                                                                                                                                                                             

Root->addChild(Rpelvis);
Root->addChild(Lpelvis);

Waist->addChild(Neck);
Waist->addChild(Rchest);
Waist->addChild(Lchest);

Neck->addChild(Nod);

Rchest->addChild(Rshoulder);
Rshoulder->addChild(Relbow);
Relbow->addChild(Rwrist);

Lchest->addChild(Lshoulder);
Lshoulder->addChild(Lelbow);
Lelbow->addChild(Lwrist);

Rpelvis->addChild(Rhip);
Rhip->addChild(Rknee);
Rknee->addChild(Rankle);

Lpelvis->addChild(Lhip);
Lhip->addChild(Lknee);
Lknee->addChild(Lankle);

Each joint is given an offset from their parent joint that is a 3 vector relative to the position of the parent.  The offsets from this skeleton are:

Root->offset = CVector3(0,60.0,0);
Waist->offset = CVector3(0,0,0);

Neck->offset = CVector3(0,20,0);

Nod->offset = CVector3(0,5,0);

Rchest->offset = CVector3(0,20,0);
Lchest->offset = CVector3(0,20,0);
Rshoulder->offset = CVector3(10,0,0);
Lshoulder->offset = CVector3(-10,0,0);
Relbow->offset = CVector3(0,-20,0);
Lelbow->offset = CVector3(0,-20,0);
Rwrist->offset = CVector3(0,-20,0);
Lwrist->offset = CVector3(0,-20,0);

Rpelvis->offset = CVector3(0,-5,0);
Lpelvis->offset = CVector3(0,-5,0);
Rhip->offset = CVector3(5,0,0);
Lhip->offset = CVector3(-5,0,0);
Rknee->offset = CVector3(0,-25,0);
Lknee->offset = CVector3(0,-25,0);
Rankle->offset = CVector3(0,-25,0);
Lankle->offset = CVector3(0,-25,0);

 

Motions are created by assigning maximum and minimum rotations in the around the x, y and z axes and functions that control the oscillation between the max and min to each joint.  Here is an example of the specification for the Root node in the rhumba:

jointDef* rRoot = new jointDef();
rRoot->maxs = CVector3(0,0,10);
rRoot->mins = CVector3(0,0,-10);
rRoot->Func1 = &s1;
rRoot->Func2 = NULL;
rRoot->Func3 = &s1;

The functions used to specify oscillation between the max and the min can really be anything that returns a float between zero and one, however to get smooth repetitive motion sinusoidal functions are used. 

    Noise is added to all the joints by composing the normal joints rotation with a rotation constructed from one dimensional Perlin noise that is ranging between zero and 10 degrees.

 

Code I borrowed and who it came from:

  1.  MyArcBall.cpp and MyArcBall.h which we altered a little and used in our camera classes were given as example code on the CS559 fall homepage and were written October, 2001 by Michael L. Gleicher.

  2. Quaternion.h and Vector3.h which are used in numerous places through out our code were written Spring 2001 by Eric McDaniel.

  3. RunButton.h and RunButton.cpp which are used to implement the play button and slider were written October, 1999 by Michael L. Gleicher.

  4. EulerAngles.h and EulerAngles.cpp which are used by the BVH to convert quaternions back to Euler angles was written by Ken Shoemake in 1993 and was taken out of the Graphics Gems 4.

  5. noise.h which is used to create Perlin noise was written by Ken Perlin and was slightly altered to suit my purposes.