Game Development Community

Too many animations! Time for IK

by Daniel Buckmaster · in Torque Game Engine · 11/06/2007 (12:20 pm) · 11 replies

All right, I guess it's my own fault for planning such an ambitious game. The universe the game will be based in (yes, I've checked the legal stuff, I don't want to talk about it right now) features many races with many, many different weapons. While I want to include only 6 races (only...), that's still a lot of weapons. The problem (or one of the problems) I've run up against is with creating and using different animations to hold and reload all these weapons.
Here's some basic requirements for character animation, my wish-list:
-Different weapons must be held in a different way, naturally
-Aiming animation should be different to not aiming (firing from the hip)
-Different skeletons necessitate different animations
-'Wobble' should be different depending on the weapon's mass and the character's strength and whether aiming or not (not required)

I did some quick calculations. With 6 races, there should be about 8 different skeletons, though not all of them need to be able to hold all the weapons (alien weapons are pretty alien, etc.). Even lumping weapons into categories that are held similarly, there's about 30 different 'hold' animations required, including turrets and melee weapons. And when you take aiming into account, that runs to a whopping 480 poses total. And then reload sequences...

So there's two obvious problems. One is the creation of such a huge amount of data. The second, and more pressing from my point of view, is that no TSShapeConstructor is going to take 30 different animations just for weapons. I have about 33 animations total in my experimental player, and that's with no weapon poses at all, and already I'm running into problems (had to increase the buffer size of something to stop a debug error).

So I thought up a few options:

-Scrap the game (hell no! Failure is not an option!)
-Restrict weapon options to their own race (that still means one race will have a load of anims, and it's less realistic and far less fun)
-Reduce the number of weapons (less fun, and still won't solve the problem, just make it more manageable)
-Implement some sort of IK (my favourite option by far...)

Running with my favourite option, just for kicks...

How would an IK system work? I'd probably use it in combination with animations. Looking at the different weapons, I can actually cut the number of poses in four when I consider only the right arm. Almost all the personnel weapons have the same pose in the right arm, it's just the left arm that varies. So what if I animate the right arm, then use IK to tie the left arm to a node on the weapon? That would solve reload animations as well - simply animate the node on the weapon to where the left arm should me moving to take out the clip or whatever, and the IK will keep up.

Frankly, the more I think about IK, the more I like it. And when you've got IK for something like thi, you can have IK for something else. Faked cloth sim, anyone? Simply tie the cloth to several downward IK chains and wave the points around, letting the bones follow. Ammunition belts? Power cables? Someone pinch me.

There's just one problem - if I tried to lift a paperweight with my programming skillz, I'd get a cramp. Still, I figure, what can go wrong? Stupid question if there ever was one...

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!


#1
11/06/2007 (12:20 pm)
Went over the maximum post length... w00t...

My idea is to use a sort of modular approach. A custom struct would store data for an IK chain of bones, containing some simple data like which bones are included, where the target point is, whether the IK is turned on, etc. A Player object might have 4 of these (really, how many IK chains do you need? 2 arms if you're desperate...) for versatility (ah), which would be initialised somewhere. Basically, you name a node IK#_# where the first # is 1-4, the index of the IK chain it's a member of, and the second # is the index of the bone in the chain (0 is the root node). Note if you only have a 1-digit index, you're limited to 9 nodes in an IK chain. I think that's plenty.
You use a console method to set the target of a specific IK chain, and another method to turn individual chains on or off. If a chain is turned on, then the IK algorithm takes over the nodes' transforms, overruling their animation. If you turn it off, animation takes over again.
So for my weapon example, you'd create the left arm as an IK chain. When the player takes out a weapon, simple turn the left arm IK on and every tick set its target position to the weapon's 'leftHand' node.
Animations would be concerned with te right arm - holding the gun, holding it in the air (or whatever you do to reload) and stuff like that.

So. Good idea? Horrible idea? Got a better idea? Pray tell.

Also... um... can somebody reccomend a good source for IK algorithms? I've searched around and found quite a good one, but I'm looking for more. The one I found is concerned with smooth interpolation of the joints - so your limb gradually moves to the right position. That's pretty good, but I'd really like to keep it simple, and do something that just finds the right transforms instantaneously (like Blender's IK system). Actually, since Blender is open-source, I could just check out its algorithm...
#2
11/07/2007 (1:23 am)
Well, good luck. I hope you find what you're looking for, but even the Blender developers themselves complained on the BConf last year that they can't find code they put in themselves...

Please note also that the use of IK will need many changes in the game engine also, if you want the IK to interact with more than the character itself, but also with the world.

Nebulagame Development
My personal blog
#3
11/07/2007 (7:34 am)
Quote:Please note also that the use of IK will need many changes in the game engine also, if you want the IK to interact with more than the character itself, but also with the world.
Yeah, I'm worried about that :P. But for this game t least, I'm concerned only with using IK to take the strain off animations. I looked up an old procedural animation forum thread which shows how to manpulate bones in a model. I was basically just going to use that, plug the IK solver into it, and add my fancy wrapper for better control.
#4
11/09/2007 (1:09 pm)
Okay, after some time to cool off, I've sbstantially revised my goal. If I'm only going to be using IK for the character's arms, and usually when they're holding some sort of gun, I may as well skip all the complicated stuff that is involved with learning and implementing true IK, and instead take a shortcut.

Each 'chain' will simply be three bones that represent an arm. Essentially, between the shoulder (root of chain), elbow (first bone to second), and wrist (second bone to third), you have a triangle. You will know all three sides (two sides are the bones' lengths; the third is the distance between the shoulder and where the wrist should be to hold the weapon), so the angles can be calculated (w00t 10th grade maths...), and more specifically, the angle inside the elbow. With this angle you can position the three bones to be holding the weapon in a natural way. Datablock and object fields can control small random variations in the angles, so everybody has a slightly different pose.
Of course, this way is less of a general solution to things; fake cloth sim is probably out, as are ammo chains. But the 'IK arm' can be used for things like turret control - when you want a character to have its hands on the turret triggers, but don't want to have to make standard poses and sizes for everything, just use IK on both arms. Same with driving vehicles.
Something cool to add would be an 'interpolate to target' feature, where you set a destination and a time, and the arm interpolates to that position in the given amount of time. That could be used for actual animation, such as pressing a button to open a door, or weapon reload sequences, where you don't want th arm to just snap to its final position.
#5
11/12/2007 (5:41 am)
Shouldn't it be possible to use a blend animation with several frames representing several "arm states" to set various holding positions (or none at all)? Much like the look up/down animation, which picks a % of the animation based on mHead.x, this animation would pick a specific frame based on what the player is holding (or driving). You could also use it to cancel the "sniper lean" many FPS character models have when not holding a weapon, or to pull the gun up to eye level when a player goes into aim mode.

Can you run another one of these constant blend animations while doing run and look at the same time? How many can you do at once? I don't know the answers, but I think it could work. Obviously changing the position of the hands screws up any animations that weren't designed to start from that position, so you have to think about how that impacts your reload animations. In fact, you'll still need separate rifle and pistol reload animations due to vastly different clip placement. For smooth transitions, there is already code to do transitions between animations; it's used extensively for Player's default movement animation, which transitions so well that you can make a crouch animation simply by making a crouch root animation and letting the interpolation handle it.

Not saying IK support wouldn't be great, just trying to come up with an easier way to get the functionality.
#6
11/13/2007 (10:25 am)
Yeah, I think blend animations are a good idea. However-
-I have heard bad things. Not saying they're true, but they put me off and immediately got me looking for alternatives, hence IK or a triangle solver.
-Still a lot of animations to create. In fact, there's probably exactly the same amount of different actual poses to create as is I had seperate DSQs for each animation. Simply less DSQ files, which is good in itself. 'Cause with the weapons in this universe, even two 'rifle' equivalents have differently placed clips, handles, etc.
-The code would be complicated to choose from such a variety of poses. I guess datablock fields and such will help, so in fact, this can be minimised. Hmm.

Quote:Not saying IK support wouldn't be great, just trying to come up with an easier way to get the functionality.
Yeah, there's definately easier ways :P. I've finished an algorithm for a triangle solver, which is sort of an IKompromise (ahahaha). Translating it to code will be the tricky part...
#7
11/13/2007 (12:14 pm)
@Daniel, I really think you're going to run into trouble if you try to use IK for too much. It's not so good at making smooth, believable animations by itself.

You may be able to get acceptable results by adding "generic" animations for things like reloading, where the animation itself merely moves the character's skeleton into a position that will allow the IK solver to reach an acceptable solution.

The problem is that due to the nature of IK in general, if you wanted to move say, your left arm from a rest pose to the magazine on a weapon it will work, but the results it gets to make your effector reach the target will *not* be even similar to the solution that a real person would get. This can result in wacky movements and other visual unfavorables. Some of that can be helped with joint limits and such things, some things to make different parts of the chain have different "weights", interpolation etc. but it's not really meant to be the end-all of animation solutions.

Also, you won't need to make a lot of code changes in the engine. Just make sure to work on the node transforms *after* tsAnimate does animateNodes() (i.e., after a shapeInstance->animate() call) so that they'll be in object space rather than parent-relative space.
#8
11/14/2007 (10:30 am)
Quote:I really think you're going to run into trouble if you try to use IK for too much. It's not so good at making smooth, believable animations by itself.
Certainly. I just want to try to minimise the amount of sheer stuff I (or other artists) have to create by letting the engine do most of the work.

Quote:You may be able to get acceptable results by adding "generic" animations for things like reloading, where the animation itself merely moves the character's skeleton into a position that will allow the IK solver to reach an acceptable solution.
Not quite sure what you mean here - am I right in interpreting this as using a generic animation to put the arm in the right sort of position, then using IK to adjust this animation for the specifications of different weapons?

Quote:The problem is that due to the nature of IK in general, if you wanted to move say, your left arm from a rest pose to the magazine on a weapon it will work, but the results it gets to make your effector reach the target will *not* be even similar to the solution that a real person would get. This can result in wacky movements and other visual unfavorables.
I'd thought of that, which is why it's necessary to still do some animation work, of course. In this case, I'd include an animation with each weapon for its reload sequence, in which the 'left hand goes here' node on the shape would be animated to move in a natural way - the IK would simply provide the arm movements to get the hand to this location. I see what you're saying, though, and it's got me worried. I'd still rather do it this way than try to create unique animations for each skeleton to hold and reload each weapon in the game.

Quote:Also, you won't need to make a lot of code changes in the engine. Just make sure to work on the node transforms *after* tsAnimate does animateNodes() (i.e., after a shapeInstance->animate() call) so that they'll be in object space rather than parent-relative space.
Thanks for the tip :). I'm not extremely familiar with the animation system - I've implemented some changes for procedural bone animation posted by John Klima, so I've got that part of it working, at least.
#9
11/14/2007 (10:45 am)
In regards to my comment about using a generic animation, I was thinking about the example of a reload. Basically what you said. You'd have the animation move the left arm pretty close to the weapon itself, then do what you planned in your original post (set a node on the weapon as the target for your effector etc.). You'll probably have to do this for most of your stuff if you're planning on using IK for much of it. But in the end you should still be able to save a lot of animations anyway.

As to John's code, I started there myself. However, I recommend *not* using the node masks at all, because some of the states they set will seriously fsck your animations in a very bad way. Don't bother messing with any of that stuff. Just pass in a reference to the mShapeInstance's mNodeTransform Vector to your IK solver and call it right before it does the (mShapeInstance->render()) and right after (mShapeInstance->animate()). Work on the transforms in your solver and store them back in when you're done. Also, his code won't help you if you want to apply IK after an animation and have it keep the animation's state properly.

IMO the best way to do it is just to create your own solver class and call it directly in your render function (i.e., in Player you probably want to make your own prepRenderImage and prepBatchRender instead of doing this in the shapebase ones). Messing with node masks and the like will seriously cause you problems, and none of them (especially MaskNodeHandsOff, which doesn't even initialize the node transforms) are suitable for this sort of thing.
#10
11/14/2007 (11:23 am)
If you implement it through the animation threading (tsThread.cpp) it's a hell of a lot less work.

Use a strategy model for your IK solver, so that you can better integrate CCD, Full-Jacobian, Half-Jacobian, and Vector based approaches to solving the chain.

Interaction with the world at large is more or less just making collision tests and transforming a point into the appropriate space (root-bone-space if I remember correctly) and basing it along as the target point for your effector.
#11
11/18/2007 (9:27 am)
Quote:You'd have the animation move the left arm pretty close to the weapon itself, then do what you planned in your original post (set a node on the weapon as the target for your effector etc.).
That's probably a good idea. I'll see how much trouble my simple triangle solver is - it could well be that I can achieve passable results with calculation and datablock values for variation.

Quote:If you implement it through the animation threading (tsThread.cpp) it's a hell of a lot less work.
I'm not really familiar with the animation code, but I'll have a look at the file you mention - thanks.