Proposed enhancement for skeletal animation

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Post Reply
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Proposed enhancement for skeletal animation

Post by sinbad » Sat May 14, 2011 12:39 pm

Hi again folks ;)

I'm probably going to be making a small enhancement to the skeletal animation system in the next couple of weeks to support an animation approach that has been requested by a client of mine. Conceptually it's fairly simple and won't change any existing behaviour, so it shouldn't affect the GSoC project on dual quaternion skinning either.

Right now, all skeletal animation is rooted on the 'binding pose' of the skeleton, ie the positions and rotations of the skeleton before any animations have been applied. Each of the keyframes in an animation use that as a delta base. The final blending if multiple animations are enabled at once depends on the blending mode - if it's ANIMBLEND_AVERAGE, the final states from each animation are subject to a weighted average, and if it's ANIMBLEND_CUMULATIVE, then each animation is weighted as it's applied and simply added to an accumulated result (also meaning that if you use a blend mask or omit bone tracks those will not be affected during the accumulation stage).

This is all fine and deals with most people's needs, but there's another angle to this, specifically with the ANIMBLEND_CUMULATIVE workflow. Some animators, when building the individual animations for a character, like to start the animation on something other than the single reference pose. For example, if the movement is small and incremental, they want to visualise it as a delta from some more common pose, like an idle pose or walking pose. It's hard to to this when all the animations have to be based on the reference pose, because either your exporter needs to be smart enough to 'subtract' the base pose the animator used while working on it, or the animator has to 'rebase' their animation once they're finished.

What they really want is to be able to export a delta animation directly from some other base pose. The simple way to do this is to treat the first frame of the animation as the base pose for this animation, instead of the single reference pose. You don't even need any more data from the exporter, except a single flag which indicates this should be the case - Ogre can then figure out the 'rebase' for itself on loading, by subtracting frame 0 from every other keyframe. An animation built like this then is only useful in ANIMBLEND_CUMULATIVE mode.

So what I propose is to support this during loading via a new flag on the Animation data, which will be optional and defaulted to the old behaviour so no assets or exporters are broken.

Thoughts / comments welcome :)
0 x

User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
Contact:

Re: Proposed enhancement for skeletal animation

Post by tuan kuranes » Sun May 15, 2011 9:00 am

Nice idea, several times asked !
Someone even solved particular problem on the forum a while ago, and ended using multiple skeleton, each with its own base pose, and one entity instance per skeleton, and seamlessly switched entity for each different skeleton if anim had different poses, which was far from ideal, but worked.

Perhaps, being even more careful with graphists, more than a simple flag, an animation time (using other frame than 0, or even other animation, so "animation name + frame" flag) would give even more flexilibility if it's not too much change ?
(Don't have the need here, it's just coming from experience dealing with graphists, or models you don't have control over...)
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Sun May 15, 2011 10:36 am

Yeah, that's a good idea, thanks. So for each animation, we'd have:

1. Base mode: either 'Skeleton' or 'Animation'
2. For base mode of 'Animation', a keyframe index indicating the base pose, default being 0
0 x

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Proposed enhancement for skeletal animation

Post by sparkprime » Sun May 15, 2011 5:03 pm

Is it really easier to support this in the library instead of as an exporter feature?

Having said this, there are so few skeletons in a typical game and the amount of new work at load time seems to be pretty low (per skeleton) so I doubt there will be any performance problems with this approach.
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Sun May 15, 2011 5:16 pm

sparkprime wrote:Is it really easier to support this in the library instead of as an exporter feature?
In short, yes. Having to implement the re-basing in every single exporter isn't something that going to happen overnight, if ever. This way, the exporter only needs to set a simple flag (easy update), or if that isn't possible, the change can be retro-fitted to the pipeline via the XML converter / MeshMagick, or could be patched in manually in code via a method on Animation which performs the adjustment. So lots of options just from one implementation.

Of course, once the adjustment is made, you could re-save the .skeleton with the Animation basis set back to Skeleton, because by that stage the adjustment has already been done.
0 x

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Proposed enhancement for skeletal animation

Post by sparkprime » Sun May 15, 2011 6:18 pm

I suppose it is analogous to tangent generation, for example, being done in OgreXMLConverter makes it easier for people to write exporters without duplicating complex code.
0 x

User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland

Re: Proposed enhancement for skeletal animation

Post by so0os » Mon May 16, 2011 9:16 am

Hey this is great! This approach could aid importing Motion Capture flicks that use a custom pose, also this would fix the issue of blenders initial bone position thingie. Great!
0 x
Sos Sosowski :)
http://www.sos.gd

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Mon May 16, 2011 3:44 pm

On review, this will also apply to pose animations - poses are usually deltas on the object space mesh position, so this would allow keyframes to be deltas-on-a-delta.

About the conversion of keyframes, my current plan is to perform this when the animation is first updated. I specifically chose not to make this on load, because for conversion tools which load & save via the serializers, you really want to save the same state you loaded, barring what the user may have explicitly changed. If you want to perform the conversion and then save (thus removing any rebase information and saving the pre-adjusted keyframes, removing the need for any in-flight conversion when you load it next time), you'll be able to do that too.
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Thu May 26, 2011 12:22 pm

Just an update to say that this is now implemented in the default branch (v1.8-to-be). I added an extra feature, which is to save the Skeleton blend mode in the .skeleton file now so that you don't need to set it manually if you don't want to. So, here's a run-down of updates and how to use them:
  1. The blending mode set on Skeleton is now always saved in .skeleton. In XML, this is just a new optional attribute called 'blendmode' which can take the values 'average' (default) or 'cumulative', and maps to the ANIMBLEND_AVERAGE and ANIMBLEND_CUMULATIVE enums. For example in XML:

    Code: Select all

    <skeleton blendmode="cumulative">
    ...
    
    This is pretty useful because you no longer need to manually call Skeleton::setBlendMode if you use cumulative blending, so long as you've saved the skeleton with this information in it.
  2. You can now make a skeletal or pose animation adjust to be a delta on a given keyframe, instead of a delta from the binding pose. The idea is that you can then use the animations relative to (say) frame 0 for accumulation purposes and it doesn't matter where your animator starts a particular incremental motion from. The base keyframe can be within the same animation (time 0 is the most popular choice), or it can be from another animation in the same skeleton / mesh. You do this via the new Animation::setUseBaseKeyFrame method. Some related points:
    • You probably only ever want to use this for ANIMBLEND_CUMULATIVE skeletal blend modes. I can't imagine why it would be useful for ANIMBLEND_AVERAGE. Mesh pose animations are always cumulative so it will always work.
    • Adjustment of the keyframes doesn't happen immediately after calling setUseBaseKeyFrame. This just registers the intention to re-base the animation when used.
    • Saving a mesh/skeleton in this state will store the original unmodified animation data, plus the base keyframe information, so that on load the same state will be restored.
    • The re-basing of the animation occurs on the first update, or you can force it earlier by calling Animation::_applyBaseKeyFrame.
    • Once the re-basing has taken place, the animation's keyframes are permanently altered, and the useBaseKeyFrame will return 'false' again. Saving the mesh/skeleton after this will save it in the post-rebased state and no base keyframe data will be saved (since it has already been 'baked' in). You could do this if you wanted to get the adjustment done offline and to not incur the re-base cost (which isn't that high) at first animation. However the original animation data before the re-base is permanently lost.
    • You can also add this information in the XML by adding an optional <baseinfo> element directly underneath the <animation> element, like so:

      Code: Select all

         <animations>
             <animation name="Sad_Add_Blink" length="0.52">
                 <baseinfo baseanimationname="" basekeyframetime="0" />
      
      If the baseanimationname attribute is blank, it means the current animation, otherwise it can be another animation in the same <animations> container (ordering doesn't matter). The basekeyframetime is a time value, not a keyframe index (so it will interpolate this if required).
I've tested this with skeletal and pose animations from a university that specialises in animation and it definitely makes things easier when you're building up composite animations including skeletal and facial variants.

Obviously at this stage, no exporters are set up to add this new metadata. For the moment, I suggest either using your own post-processing pipeline (you just need to load the files, change the details as above, and re-save using the serialisers), or just use OgreXMLConverter to expand the media, insert the new elements, and convert back (this is how I modified my existing test assets). In time, exporter writers can hook into these new options as and when they wish to make the process smoother.

I hope it helps!
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 3998
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 192
Contact:

Re: Proposed enhancement for skeletal animation

Post by dark_sylinc » Fri Jun 10, 2011 2:36 am

sinbad wrote:
  1. You can now make a skeletal or pose animation adjust to be a delta on a given keyframe, instead of a delta from the binding pose. The idea is that you can then use the animations relative to (say) frame 0 for accumulation purposes and it doesn't matter where your animator starts a particular incremental motion from. The base keyframe can be within the same animation (time 0 is the most popular choice), or it can be from another animation in the same skeleton / mesh. You do this via the new Animation::setUseBaseKeyFrame method.
  2. Adjustment of the keyframes doesn't happen immediately after calling setUseBaseKeyFrame. This just registers the intention to re-base the animation when used.
  3. The re-basing of the animation occurs on the first update, or you can force it earlier by calling Animation::_applyBaseKeyFrame.
This means, from a mesh viewer point of view, (Ogre Meshy) the user would select the animation he wants to play, then select another animation and choose a key frame from it to use it as a base for the first animation?
(That is of course, unnecessary if the .skeleton already contains the base info for that particular animation)

I haven't seen the code yet, but is the base is a "keyframe", or a "time in seconds" snapshot (i.e. the base can be a bone position between two keyframes)?

The point of having a good mesh viewer is keeping it up to date ;)
I don't plan it to be fancy as it is an advanced animation feature worth of a special animation editor, but at least one should be able to play with the basics of it, not to mention preview it.

Cheers, and keep up the good job
Dark Sylinc

PS: Been busy as bloody hell, hopefully it won't require much change ;)
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Fri Jun 10, 2011 10:06 am

dark_sylinc wrote:This means, from a mesh viewer point of view, (Ogre Meshy) the user would select the animation he wants to play, then select another animation and choose a key frame from it to use it as a base for the first animation?
(That is of course, unnecessary if the .skeleton already contains the base info for that particular animation)
You could do that yeah, although I expect this to be most useful during export. But for sure you could add features to mesh viewers if you wanted to tweak an existing animation setup without re-exporting. You'll probably have 2 different kinds of animation, the 'main' ones which affect everything and are rooted on the base pose, and the 'refinement' ones which are layered on top to create cumulative effects, and which the animator may have preferred to create on top of some other active pose because it was more natural to do it that way. It's the latter that you'd want to set to be relative to another keyframe (probably at time 0).
dark_sylinc wrote: haven't seen the code yet, but is the base is a "keyframe", or a "time in seconds" snapshot (i.e. the base can be a bone position between two keyframes)?
It's a time, so in theory the base state can be an interpolated one, although in practice that's not very likely, I expect time 0 to be used in the majority of cases. Also the base animation itself doesn't have to be the same one, although again most of the time it's most convenient for that to be the case. So in the most common case the animator just re-poses the model in their animation at frame 0 as a starting point, and the difference between that and the base pose is ignored for applying this animation, only the difference between that first frame and the rest of the animation is applied.
dark_sylinc wrote:The point of having a good mesh viewer is keeping it up to date
I don't plan it to be fancy as it is an advanced animation feature worth of a special animation editor, but at least one should be able to play with the basics of it, not to mention preview it
The nice thing is that simply re-building it will pick up the new features as far as playback is concerned, but if you want to allow editing of it then yeah you have some extra work :)
0 x

Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France

Re: Proposed enhancement for skeletal animation

Post by Nodrev » Fri Jun 24, 2011 6:40 pm

Great, our team often ask herself in the past why those skeletal animations were not using delta times, as it's the way most of other engine and modellers does.
0 x

maxiwill
Halfling
Posts: 45
Joined: Sat May 22, 2010 8:43 am

Re: Proposed enhancement for skeletal animation

Post by maxiwill » Tue Jul 12, 2011 6:20 am

hi!

I have a question about the line sinbad stated "For example, if the movement is small and incremental, they want to visualize it as a delta from some more common pose, like an idle pose or walking pose" :

In my project, I need to apply dynamically calculated direction vectors or a delta of pose ( like say walking a step is 1.0 of the walk pose, walking halfway would be 0.5), to certain bones of a mesh

i think i'm right in saying that this feature is exactly what I need to accomplish that right ? :D

also, where can I download the updated source, the "v1.8-to-be" version ?

i looked up the download links provided but didnt see it :(

when will it be released?
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Proposed enhancement for skeletal animation

Post by sinbad » Tue Jul 12, 2011 10:38 am

You can only get the code from Mercurial right now, please see http://www.ogre3d.org/developers/mercurial

Procedurally generated animation isn't really affected by this. It just allows animators to work from a different base keyframe for each animation if they want. Procedurally generated or dynamically calculated animation behaves exactly as it did before - ie it was always possible.
0 x

Post Reply