[2.2] Skeletal Bone Animation Problem

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

[2.2] Skeletal Bone Animation Problem

Post by crancran »

So I have a skeletal bone animation where I have 21 different bones that have the following bone structure:

Code: Select all

 0 1 2 3 4 5 6 7 8 11 12 13 14
                 |
               +---+
               9   10
                   |
       +---+---+---+---+---+---+
       15  16  17  18  19  20  21
The animation key frame sequence is quite simple; bones are animated with either a position-based key frame or a rotation-based key frame. The one and only exception is bone 10, which is animated with both a position and rotation composed key frame.

In the animation sequence the following are true:
  • Bone 8 is fixed at origin, has no key frames
  • Bone 9 is animated by position only, shifting in the -Z direction by distance of A
  • Bone 10 is animated by both position and rotation, shifting in -Z direction by same distance as 9 and rotates upward by 45 degrees.
  • Bone 15, 17, 18, 19, and 20 are animated by rotation only
  • Bone 16 is animated by position only.
The problem I have concerns only Bone 10.

If I construct the animation sequence with only position changes (only calling setTranslate) then the mesh influenced by Bone 9 and 10 move in unison the same distance making the two parts look as if they're one as I would expect. When I construct the animation sequence with both position and rotation (calling setTranslate and setRotation) then I find Bone 9 continues to move as expected but Bone 10 moves in the -Z direction slight less than before creating a break in the mesh where one isn't expected. To make sure none of the child bone key frames are impacting Bone 10, I also tested not animating any of the children of Bone 10 and when both position and rotation is applied, it moves with the same distorted distance.

Anyone have any ideas what it could be?

UPDATE 1
I decided to initially set the animation frame to the point where the mesh has moved the maximum -Z distance from the binding pose and froze. I checked the bone positions for 9 and 10 and regardless of whether rotation is applied or not 'bone->getPosition()' is identical. I don't know if this matters or not but it makes me believe then there is an issue with how the animation is being interpreted down the pipeline somewhere?
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

Re: [2.2] Skeletal Bone Animation Problem

Post by crancran »

So after some debugging I believe what I found to be the problem.

Code: Select all

  for ( size_t i = 0; i < bones.size(); ++i )
  {
    const BoneDeclaration &bd = bones[i];
    
    // Create bone and set its position
    Ogre::v1::OldBone *bone = skeleton->createBone( bd.getBoneName(), bd.getBoneId() );
    bone->setPosition( bd.getPosition() );
    
    // Attach bone to parent if it has a parent
    if ( bd.hasParent() )
    {
      Ogre::v1::OldBone *parent = skeleton->getBone( bd.getParentBoneId() );    
      parent->addChild( bone );
    }
  }
The issue here is that the bone declaration position is in model world space, not local space which for child bones was the source of the problem. I changed the function to the following and that problem seems to have disappeared.

Code: Select all

  for ( size_t i = 0; i < bones.size(); ++i )
  {
    const BoneDeclaration &bd = bones[i];
    
    // Create bone
    Ogre::v1::OldBone *bone = skeleton->createBone( bd.getBoneName(), bd.getBoneId() );
    
    // Attach bone to parent if it has a parent
    if ( bd.hasParent() )
    {
      Ogre::v1::OldBone *parent = skeleton->getBone( bd.getParentBoneId() );    
      // Child bone positions are in model world space coordinates, meaning they're absolute from the model's origin.
      // Ogre wants these to be provided in local space relative to the parent bone instead.
      Ogre::Vector3 position = parent->_getDerivedPosition();
      bone->setPosition( bd.getPosition() - position );
      parent->addChild( bone );
      continue;
    }
    
    // For non-parented bones, its safe to use the model world space position
    bone->setPosition( bd.getPosition() );
  }
The next quirk I see is when applying rotation, it's causing some deformation of the model or erratic shakes at certain key frames as if there is some form of gimbal lock at play. I'm still debugging to see if I can understand that but I would like to know if what I determined above is correct?
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

Re: [2.2] Skeletal Bone Animation Problem

Post by crancran »

I believe the last problem I have is with how I generate the key frames.
There are situations where bones will have key frame time data like:

Code: Select all

Position Time (ms): 0, 1000, 2000, 3000
Position Values: v0, v1, v2, v0

Rotation Times (ms): 0, 500, 1000, 1500, 2000, 2500, 3000
Rotation Values: q0, q1, q2, q3, q4, q5, q0
This gets generated as

Code: Select all

KeyFrame: 0, v0, q0
KeyFrame: .5, q1
KeyFrame: 1.0, v1, q2
KeyFrame: 1.5, q3
KeyFrame: 2.0, v2, q4
KeyFrame: 2.5, q5 
KeyFrame: 3, v0, q0
The key frames where I have not explicitly set the position will have Vector3::ZERO position, which I suspect is what is causing the erratic movement for specific models during certain animations. For a situation like this, what does OGRE expect I provide here?

From what I can tell from the source code in OgreSkeletonAnimationDef.cpp where TransformKeyFrame is used, it would appear you must construct key frames with both values; there does not seem to be support for one or the other.
crancran
Greenskin
Posts: 138
Joined: Wed May 05, 2010 3:36 pm
x 6

Re: [2.2] Skeletal Bone Animation Problem

Post by crancran »

I ended up applying interpolation between the various timesteps of the key frames guaranteeing that all key frames have a position, rotation, and scale and the animation sequences run smoothly. Turned out to be an interpretation problem of my external data XD.
Post Reply