Skeletal system

 

            Upon research of current Kinematic systems, I have found that other than common sense joint manipulation, no one really knows what they're doing.  There are some algorithms for Inverse Kinematics, but they all have their flaws, making them unusable to properly, let alone quickly, emulate human behavior.

            I plan on using a tree/branching structure to implement a bone system which will hopefully be easy to map textures and meshes too.  I have no experience in this field, so I expect many flaws. 

 

The bone system will be joint based.

There will be one starting, or base joint per skeleton which will serve as the root of the system. 

-This base joint cannot be rotated. 

-For humans and other animals, it should be something like the hip or a joint on the spinal column. 

-For animals like snakes or eels, the base joint should be the tail tip, or head.  -For something like a plant, the base joint should be the piece of the plant that intersects the ground. 

-I recommend these places because the skeletal entity can be easily visualized and rotated in the coordinate system using this base joint.

 

Joint Data

-each joint will contain the number of joints that it is attached to

-joints do not have to be a single link

-joints will have a joint rotation normal, which will represent the direction that the joints attached to it go if they have a 0 for horizontal and vertical rotation information

-the joint will not carry information about the joints that are attached to it, but an array that contains them.

 

Joints will contain their own information about thier attachment rotation.

-i.e. the elbow joint will contain it's horizontal and vertical rotation with respect to the shoulder joint

-joints will also contain rotational restrictions.  This will be used in an Inverse Kinematics system, and will prevent impossible contortions.

-joints will contain their distance away from their parent joint, this minimizes the amount of data that we have to carry around and should make everything more efficient.

 

Drawing

-amazingly, drawing should be recursive:

 

Joint::Draw

{

  PushMatrix();  //return for the next child on this level

  rotate the system for this.horizrot and this.vertrot; //the system's origin should be at the parent joint normal here...

  translate the system the distance of this joint;

  actually draw this joint;

  rotate the system for this.rotnormal; //do this before drawing the children, who need the system in this rotation to draw properly.

  loop(children)

    child::draw;

 

  //when no children are left, or none to begin with

  glPopMatrix(); //return state for the next child at this level

  return;

}

 

-rotation will be done using two variables, a horizontal rotation (using the y axis) and a vertical rotation(using the x axis).  I used this type of rotation in my particle system for bilboarding and it worked very well.  With a very minimal amount of overhead.

-some rotating has to be done before the children are drawn to put the coord system at the joint rotation normal for that parent joint...

-the base joint has a rotation of zero, in fact, base joint is a subclass of joint, so the draw function will just be overridden and changed accordingly

 

Let's look at an example:

 

A Flower consisting of 5 joints:

 

joint1 //base joint, move the coord system to the place where the flower intersects the ground then call draw on the flower

numchildren = 1;

children[1] = {joint2};

//rotationnorm = 0; //this is always straight up in the position of the system at the time of the draw.  Does this need to be changed?

 

joint2 //first link

numchildren = 3; //has two leaves here and another joint above

children[3]={joint3, joint4, joint5};

rotationnorm=(0,1,0); //straight up, the syntax might have to be changed, depending on what's easier in OpenGL

horzrot = 0; //direction of the joint

vertrot = 0;

defaulthorzrot = 0; //these will set the system back to its resting position

defaultvertrot = 0;

distance= 5; //arbitrary

horzmax= 90; //this is dependant on how we define the joint, if you twist a flower stalk, it can't go more than a quarter turn.

horzmin = -90;

vertmax = 90;

vertmin = -90;

//the above are pretty good range of motions for a flower, they're believable at least for this demonstration.  With these values, we can't have the flower spinning around on the ground using IK, which would be impossible.

 

-the rest of the joints work similarly, except the leaf horzrot and vertrot will point them towards the side of the flower instead of straight up, something like horzrot=90 or -90 and vertrot=70.  These will be the defaults too.

-the max and min rotations are based on the rotated joint, so if the default is 90 above, the real min and max would be 0 and 180 respectively.

 

Hopefully this is a good enough start to begin coding.  I've tried to make it as intuitive as possible because millions of years of evolution has probably already worked out the best way of doing Inverse and Forward Kinematics.

 

I'm also looking to extend this into mesh deformation.  If we just use polygons and draw them around the points to simulate a body, it would work, but it would look crappy, kind of like the bodies in FF7.  Hell, like the bodies in tons of games.  If, however, we use a mesh and make its points dependent on the rotations and positions of specific joints, some amount of deformation will take care of itself.  This would work especially well for textures, like textured skin for instance, if you used a texture of clothing or maybe a tatooed arm instead of using all those polygons, the texture would stay in the same place that it should be relative to the way that the joints are positioned.  This would work really well in the above flower example, where the joints would consist of rings of verticies that would map to a specific vertex on the ring above.  Unfortuantely, I don't know how to implement this yet.

 

Milestones:

 

implement the joint system using GL_POINTS and GL_LINES.  This should give a nice little stick man.

 

Try and make him move around with Forward Kinematics, it shouldn't look too good, but see if it *can* look somewhat 'real'

 

give the stick man some bulk with various polygons.  At least a head.  For the polygon and vertex mapping, the recursive draw method that I described above might not work because the polygons will get split up.  It might be a good idea to have a get position function that will return the joints coords and it's up vector.  That way a polygon mesh can draw itself in one shot as long as it knows which vertecies are assigned to which joint.  Seems pretty advanced.

 

Try to give the stick man some real shape with a polygon mesh that knows its own relation to the joint system.  Take the simple flower example again.  The ring that makes up the bottom of the flower, knows that it is 1 unit away from the base joint starting in the direction of (1,0,0) and continuing in a circle for 6 points.  At the second joint, the ring should be tilted at an axis equal to the current rotation of the joint.  that way, one side of the polygon stretches and the other side shrinks.

 

Scripting?  Yea right, this project is out of control, you can't stop it, you can only hope to contain it.

 

SEE YOU AGAIN SPACE COWBOY...