3D Animation Changes

Hi all,

I’ve just committed some minor changes that aren’t quite minor enough to not post about.

First of all there were a couple of nasty memory leaks in KeyframedModel.dispose() and TextureDict.unloadAll() that are now fixed – if you were using either of these I’d highly recommend you update. I promise to be more diligent with cleaning up my shit in the future!

Secondly the animators now use a WrapMode instead of a boolean loop argument. A new WrapMode I’ve implemented is SingleFrame, which plays 1 frame of animation then stops. This is to get models out of bind pose into a ‘frozen idle’ with very little performance cost. When I implemented it in Discretion my framerate jumped by about a bazillion FPS. Okay not quite, but it was highly significant for any scene with more than a couple of characters. I recommend using this on Android for all idle animations unless you can definitely afford to be doing all that interpolation every frame.

Minor but useful addition to KeyframedModel

One of the benefits of using skeletal animation systems is you can use the joints for other things besides skinning geometry, like attaching weapons to hands: the joint name (for example “r_hand”) is specified in attachment code, which then transforms the attached object to the same place the hand is at.

KeyframedModel is faster than using MD5 animation because it optimises away the skeleton and skinning calculations, replacing them with “dumb” interpolation of the vertices for each mesh.  The problem with using KeyframedModel is you’ve then sacrificed information that could be useful for other things, like attaching weapons. To workaround this issue, I’ve added a ‘tagged joints’ system: before you call sampleAnimationFromMD5, send your model some joint names as an arraylist by calling setTaggedJoints(), and the sampling will add the joints you specified to its keyframes. Interpolation of the joints is also done for you if you tagged any. You can then use getJointData to get a Vector3/Quaternion pair representing the joint’s location in model space. Some things to note:

1. Integer indices are used internally. The index corresponds to the joint tag’s position in the arraylist you passed in. If you have more than one or two you might want to maintain your own lookup table of joint tags to indices.

2. Currently no post-processing is done on the joint names as parsed from the md5mesh file – this means at the moment you’ll probably have to use strings like “\”r_hand\”” (note the extra, escaped double quotes).

3. I haven’t measured the performance impact but it should be minimal so long as there aren’t lots of joints being interpolated.

Hope you find it useful!