Repository navigation
fix(ltk_anim): read and evaluate the newer exporter's compressed animations - #262
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Compressed animations from the newer exporter crash or collapse in
ltk_anim. The latest Janna skin (skin 67) is the current example: ltk-manager reportsInvalid 'flags' - got '60'and panics in the preview. Four fixes, each checked on the 324.anmfiles inChampions/Janna.wad.client.1. Unknown flag bits rejected the file.
AnimationFlags::from_bitsis strict, and shipped files use bits up to0x20(Janna's are0x3C). The flags are now read withfrom_bits_retain, withconst _ = !0. 341 of the game's 34,601 compressed.anmfiles failed to parse before this.2. A track with one key panicked. These files store a transform that never changes as a single key, so all four spline keys share one time. The weighted (
0x4) path had not1 == t2guard, unlike the uniform path. The weights grew to about 1e27, cancelled, and the rotation summed to exactly zero, soQuat::normalizepanicked (normalized.is_finite()). The same cancellation silently returned zero for translation and scale. It now returns the key, as the uniform path already did. This affected 35 of Janna's 324 files.3. A transform without keys stopped playback. The jump cache marks a missing transform with index
0xFFFF, and that index was folded into the frame cursor. The cursor then skipped past every frame, so no key after the jump cache was read and the spline extrapolated. Janna translations reached 27,861,528 units and a second glam assertion panicked. Out of range indices now leave the cursor alone.4. A transform without keys sampled a zero scale. The hot frame default was
Vec3::ZERO, which collapsed 11,627 joint tracks across Janna's files. It is nowVec3::ONE, which matches the rotation default ofQuat::IDENTITY.After the fixes, all 324 Janna files parse, and sequential playback at 120 Hz gives finite poses. Rotation steps match the raw key deltas. The largest remaining jumps (about 2.4 rad in
dance_loop) are in the keys themselves.Flag names. Only
0x4is read by the client (CompressedAnimationAsset::Evaluate, 16.15). The other names come from a census of every shipped compressed file.0x2and0x8are deliberately not given a guessed meaning. The type is crate-private, so the rename to SCREAMING_SNAKE_CASE (C-CASE) changes no public API.0x1SUB_FRAME_KEYS0x2EXPORTER_OPTION_10x4USE_KEYFRAME_PARAMETRIZATION0x8EXPORTER_OPTION_30x30PRUNED_TRACKSNot in this PR. A joint with no keys for a transform most likely keeps its bind pose.
evaluatereturns a full transform for every joint, so it cannot say "not animated", and missing rotation and translation still sample as identity. Fixing that needs an API change.Each fix has a regression test (in
tests/compressed_jump_caches.rs) that fails before it.Made with the help of an LLM. Every fix was checked against the shipped Janna files, and the flag statistics against every shipped compressed
.anm.🤖 Generated with Claude Code