-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animation compression #731
Comments
You can easily sample to whatever fix frame rate you need when loading the animation data. There is no need to bloat the animation size in the transmitted data. |
The "compression" wouldn't bloat the animation size. More than likely it will significantly reduce the animation size considering the current format requires you to store multiple time tables to be able to use different sampling rates per channel. Even if the animation size is the same, decoding the "compressed" format would be much more efficient than searching through multiple time tables. Doing the "compression" at load time defeats the purpose. |
@mre4ce sounds like you have a prominent use case here and that we should update the spec accordingly. I am oversimplifying this by suggesting that just a |
I meant:
|
I'm not quite sure what you mean with the "scale / stride". A fixed rate animation makes it easy to lookup key frames.
However, we still want to omit key frames that are not necessary. The keyFrameIndex gets us the blockIndex:
The offset to the block can be looked up directly from "channel.blockOffsets". The block then stores a bit mask of "channel.framesPerBlock" bits with a bit set to one for key frames that are actually stored, followed by the actual key frame data itself. Independent from this encoding scheme you would store the 'translation', 'scale' and 'rotations' as 16-bit per component values. To make this flexible you store a "scale & bias" per channel for the 'translation' and 'scale' and you store the largest three components of the 'rotation' quaternion (assuming the quaternions are always normalized). Now this is just one idea. It'd be good to hear suggestions from others before committing anything to the spec. |
Ah, OK, this sounds like a pretty significant breaking change. It could be worth it for the memory savings, but this would have to come post |
Orthogonal to this issue, we are also interested in keyframe animation compression in the same sense as mesh compression, #874 |
CC Draco animation compression, #1407 |
This could be a nice gain in addition to potentially using Draco compression. If this is useful to anyone, please provide a proposal; closing in the meantime. |
The current setup for animations does allow for some level of "compression". You can obviously omit channels that are not animating, but you can also choose different sub-sampling rates for different channels. However, the latter requires lookups in separate time tables which is not necessarily cheap. Sure you could make the animation system stateful but imho that's just a bad idea (state is the root of all evil). You want to be able to start an animation at any time or play from any point without relying on previously stored state. You can do a binary search through a time table but this is still a log(N) operation which is time consuming for long animations.
In the past I've primarily worked with animation systems that use a fixed sampling rate per animation or channel. This gets rid of the expensive time table lookups. Additionally it makes it easier to omit key frames based on whether or not they can be derived with interpolation. Next to an animation with a fixed sampling rate you can store a bit field with a bit set to one for each key frame that exists. Simple bit operations (bit-count, leading-zero-count etc.) can then be used to directly lookup key frames from this data.
The following example shows a simple example of what this could look like:
Each channel lists the "node" that is animated. The channel lists the "property" of the node that is animated. This is either "translation", "rotation" or "scale". The frame rate of the channel is listed as "frameRate". The animation data is stored in blocks of "framesPerBlock" frames each. The offset to each block can be found in the "blockOffsets". The blocks themselves are stored in "frameBlocks". Each block starts with a bit field of "framesPerBlock" bits. This bit field has a bit set to one for each key frame that is actually stored. A block always stores an initial key frame but any successive frames may be omitted. The initial key frame of the next block is the last key frame of the current block.
Note that this is just an encoding of effectively the same thing. As opposed to using a non-fixed-rate animation with a different time table per channel to space out the key frames differently, the animation is now fixed rate and key frames are explicitly omitted.
The text was updated successfully, but these errors were encountered: