State of the Art - 3D Animation Compression?

Started by
7 comments, last by thatguyfromthething 14 years, 1 month ago
I'm wondering, what algorithms are current-gen/next-gen engines using for compressing animation? Quantization? How are they saving data, one matrix, one translation vector + quaternion, or a different way? EDIT: I meant to say animation in three dimensions. [Edited by - gsamour on February 22, 2010 2:58:06 PM]
Advertisement
I'm referring to Doom III so this isn't exactly current-gen, but they didn't do any compression (apart from their usual habit of packing all resources into archives). They just dumped the numbers into a custom text file format.
It's still small compared to all the textures an stuff and these days nobody cares about (hdd-)memory.
As for the other two questions, no artificial quantization was applied. If memory serves well, they chose quaternions over rotation matrices and only stored the imaginary components because the real part can be reconstructed (all rotation quaternions have length 1).
If you're so concerned about the space your animation takes, throw away the position vectors and store the rotations using a polar coordinate system. 2 32bit floats.
snake5, can you please elaborate? For example, take the following animation keyframes:


keyframe 1: position(0,0,0) rotation(0 deg). (object is facing positive Z axis)

keyframe 2: position(0,0,0) rotation(90 deg). (object faces positive X axis)

keyframe 3: position(5,0,0) rotation(90 deg). (no rotation but move 5 units in X)

how would you save that in polar coordinates?
Quote:Original post by gsamour
snake5, can you please elaborate? For example, take the following animation keyframes:

keyframe 1: position(0,0,0) rotation(0 deg). (object is facing positive Z axis)

keyframe 2: position(0,0,0) rotation(90 deg). (object faces positive X axis)

keyframe 3: position(5,0,0) rotation(90 deg). (no rotation but move 5 units in X)

how would you save that in polar coordinates?
I believe that the point snake is making is that you can't translate a bone.

Try rotating your arm at the shoulder - easy. Not try translating your arm at the shoulder - not going to happen. You can translate the shoulder, but only by rotating your torso, or translating your entire body (i.e. by walking).

With that in mind, you only need to store rotations or each bones, plus a single translation for the model as a whole.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by swiftcoder
I believe that the point snake is making is that you can't translate a bone.

...which is incorrect. Why can't you translate bones? Maybe it doesn't make sense in certain situations like joint animation, but that's not the only kind of animation there is, and you're going to have a lot of angry animators on your hands if they can't translate bones.

At the end of the day, animation data tends to be so small compared to everything else that you probably don't really need compression, at least not until you determine that your animations are taking up a ton of space. The combined animation data for both our major MMO projects is ~15MB, and this is before running a standard zlib pass over them.
There are different techniques for compression animation data.

Animation data can take a very big amount of space in memory, when we don't talk about the simple Quake style games. Actually storing uncompressed animation data could take over 100 mb quite easily.

First of all, don't store what you don't need. And store your data in relative space to the parent. Often certain bones do not animate, like fingers bones. Instead only the arms would rotate for example.

Also don't store position data if there is no position animation for a given bone. Quite obvious, but adjust your data structures to that. So store position, rotation etc separately. Next to that think of using techniques like realtime motion mirroring and motion retargeting to reduce the amount of motions you need.

There are different techniques you can use to compress the animation data. To mention some. Some of those can be combined of course:

1.) Quantization: Do not store your float values as floats, but pack them in less bits. For example you could store your rotation quaternions component values in 4 16-bit short values, instead of 4 32-bit float values.

2.) Calculate the w coordinate of the quaternion. Or store in spherical coordinates. This depends on if you want to prevent conversions, and on some other factors. This also doesn't always work perfectly for all animations.

3.) Keyframe reduction: Remove keyframes that do not introduce much error when you remove them. Think of an object having the same rotation for a while, or even a linear motion at a constant speed.

4.) Fit a spline through your set of keyframes to approximate the signal with a curve such as a b-spline.

5.) Compress the animated values using wavelet based compression. Basically you chop your motion data into chunks. Then you can build a signal for each component like the quaternion x y z and w. Then transform into wavelet coefficients and quantize. Then run for example a Huffman coder over those values to compress the data. You need a caching system for this also.

Each of those techniques have their own pros and cons in terms of performance. Best is to support all these techniques. For example I used wavelet compression for cutscenes sometimes, while keyframe reduction/optimization was used on most of the non-cutscene in-game data for performance reasons.

Hope this gives you some ideas :)

- John
Thanks to everyone for their insight into this topic!

Buckshag, great ideas... I found another thread that discusses #2 further, as well as other ideas...

http://www.gamedev.net/community/forums/topic.asp?topic_id=461253
For games? You don't really want to compress things in the traditional sense if it in use because you will be accessing it every single frame. Quantizing will usually make you faster, though, not slower.

This is my thread. There are many threads like it, but this one is mine.

This topic is closed to new replies.

Advertisement