Ok so this might be pretty long but I think I found a solution to this issue. I'm writing all of this as a resource for anyone who might be interested in working on animation for STK as well.
The short version is basically that, as far as I can tell, Blender doesn't update pole targets in the same UI update as the rest of the IK chain on Suzanne's legs. I'm using Blender 2.79 and I don't know if this is consistent across versions but I'll come back to this issue in a little bit.
The way that the animations are setup in my .blend file is that everything is animated on the main timeline. I'm new to Blender and don't yet understand actions and the NLA editor so everything is just dumped onto the main timeline. That means that an animation set's <start> frame isn't isolated from the previous set's <end> frame. For simple rigs with only FK controls or objects animated using only their LocRotScale (I believe this is called IPO in Blender?), this wouldn't present an issue in itself. This is because the exporter iterates over every frame in the timeline and grabs the information from every keyframe in every bone and for objects animated without bones, the IPO keyframe data is used instead.
The issue I'm having with Suzanne's knees is because Blender seemingly doesn't compute IK bone rotation using pole targets in the same update frame as the rest of the armature. This means that when the exporter iterates over the timeline, looking for keyframes,
it's getting rotation data for bones that haven't fully updated yet.
I've included an example in this gif:
- Example of updating IK chain late
You'll notice that in the example, I'm going frame by frame using the right arrow key and that I reach the end of one anim set on frame 196 and start the bum spanking anim set on frame 197. On frame 197, the pole targets (the selected objects) are in their proper place but the knees are all messed up. One frame later though, the knees are rotated correctly and the pole targets haven't moved (besides the slight inherited movement from the parent object). This is where the funkiness was coming from in the earlier gif of Suzanne in-game.
Now for the solution. It is admittedly very hack-y but it gives satisfactory results; at least until a better solution is found. I ended up shifting every keyframe in the animation set forward by one frame and duplicating the keyframes on the <start> frame. This means that frames 197 and 198 in my blend file are
identical. Then I made sure that the <start> timeline marker was only on frame 198.
Here's an example:
- Example of solution to late IK update
The leg bones are still always updated one frame late but as long as the pole targets don't move very much from one frame to the next, it's almost impossible to tell that it's incorrect.
Now I suppose it's worth talking about "real" fixes to the problem and not just silly solutions. I believe the problem comes from Blender. I've tried Googling the issue of the IK chain not updating all at once but can't seem to find any one else talking about it. I also don't have the expertise to comb through Blender's source files and confirm whether or not updating IK chains on a different update call is intentional.
Perhaps there's a way to invoke an extra update through the Blender API? This could be done in the spm exporter before grabbing the keyframe data. This would ensure that the data is correct and not "off by one frame". But again, I believe this is only possible if there's an API method to invoke an update without changing frames. I don't know Blender's API so maybe one of the devs could confirm or deny this.
Another point is that this behaviour could be different in 2.80. I haven't had the chance yet to try 2.80 but that doesn't change the fact that the STK Addons don't yet support 2.80 so animations couldn't be exported anyway. But it's possible in the near future that this won't even be a problem anymore.
One last point I can think of is that perhaps my armature isn't setup properly. I have the pole targets setup as empty objects that are parented to the root bone. I've looked at other videos and tutorials since then and it seems that the "normal" way to setup pole targets is to use actual bone objects that are a part of the armature. That could be why the rotations on the IK chains are being updated later. I haven't been able to test this yet but I would like to in the near future and if I do, I will post an update.
Also, if I got any information wrong, please let me know! Like I said, I'm new to Blender and STK and there's a very good chance I've misunderstood some implementation details. And I realize all of this work for a background character seems crazy but I would like to contribute some more significant pieces to STK in the future and I think this is a good opportunity to identify some technical boundaries.
EDIT:
I forgot to add an example of the fixed monkey in-game!
- MonkeyKnees fixed
- monkeyKnees_fixed.gif (561.68 KiB) Viewed 11649 times