Advertisement

Root bone moving character

Started by April 14, 2018 10:03 AM
2 comments, last by Kundelstein 6 years, 9 months ago

So I have probably common question but somehow I got stuck and need a little help.

I managed to glue together skinned character animation player in C++/OpenGL (though it really does not matter). As an input I use MD5 (3d models from Doom) and Spine2d (2d animations in JSON). Everything works like a charm, with full blend tree support, skeleton deforming on GPU by supplied positions and quaternions, just like mama tough us with MD5. 

The problem started when I tried to add a proper animation from root bone:

To make blending between 2 animations a bit better, I had to remove the root bone rotation and position so the bones will "morph" more locally - otherwise If I mix animations '90 degree rotating' with 'standing still' the bones would be placed in bad positions. This is because positions are lerped, so they move on straight line. At the end of animation I just add the root bone to the whole skeleton and everything looks fine. This also served as a base to object moving.

As we all know, after the walk cycle such animation will pop to the start position. Unfortunately, to make object move, I  can't just add the animation delta at the end of the cycle. This is because if I change the animation weight, the end position will get weighted too. I just checked the Doom3 source code and it looks like they are storing animation delta of the full step, but maybe it is for evaluating where the animation will end up (AI and such). 

For now I assumed that I just need position. I store the root bone position before the frame time update as some additional old_root_bone joint. Than I pass this old_root_bone with all other bone positions (including the root bone itself) and when I'm ready to draw I can extract the difference in step and add it to the character position. It works.

Some minor thing to figure out is if I should take into consideration the Bind Pose of the root bone and add it somewhere.

The problem is that I have no clue what to do with the rotation. I have noticed, that some animations (I 'borrowed' animations from Batman Arkham series, as those are well suited for full character animation) rotate root bone as they please - for example in running animation the character is leaning forward - and if I rotate the model by difference in animations - I end up with character moving like hamster in the wheel.

 

So after this wall of text my questions are:

1. Am I doing the moving character from the root bone correctly?

2. Is this a common thing to ignore rotation and do it somehow manually in script? Eventually I can extract only single axis animation and use this, but I have no idea if that is a proper choice.

3. What are common practices for this kind of animations?

 

I'm attaching a short movie how the things look like. The 3 buttons below are:

- node stand/walk/run - anim weight

- node stand/rotate90/rotate180 - anim weight

- cross between the above 2 nodes (actually it is the weight of the turning node, but it is the same thing in this case)

 

BatWalk0001.mp4

BatWalkImg.png

Are you talking about something like this? http://polycount.com/discussion/179132/in-place-animations-vs-moving-animations

I've generally called this "treadmill" vs. "non-treadmill" keyframe animations ... and yes, in non-treadmill animations, the root bone is translated by the keyframes, whereas in treadmill the engine is responsible for translating the character via its world matrix for example. Different assets and game engines handle this differently. Dark Age of Camelot is strictly treadmill animations for instance and TitanQuest Immortal Throne is strictly non-treadmill animations.

Advertisement
On 4/25/2018 at 6:34 AM, Steve_Segreto said:

Thank you for the link. It was helpful.

Yes, I was trying to make a non-treadmill system, so the whole animation would be self efficient in terms of motion (though gameplay tweaking of such system is probably nightmare).

I ended up with such solution: I add one extra virtual bone to the system which is holding root bone position before current update. then I mix all animation layers. Then I have new pose to display and I can calculate delta like this: delta = old_root_bone_pos - root_bone_pos;

I don't really handle rotation right now but if necessary, I will just get single axis, as some animators tend to lean root bone to make characters look like running.

Noticed that some programmers do it a bit differently - they generally calculate delta of the whole animation just after loading and then they "convert" the animation to treadmill by moving root bone linearly by the constant step, where step is calculated like: step = delta / number_of_anim_frames;

The second approach seams a bit like cheating and won't work with complex animations but maybe it is not really a problem, specially if we put collider in root bone position and not at character origin position. I don't really know - I'm too noob in animation systems. 

 

This topic is closed to new replies.

Advertisement