godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.1k stars 21.18k forks source link

Animation compression has incorrect rotation #96882

Closed fire closed 1 month ago

fire commented 2 months ago

Tested versions

System information

Mac Mini, Apple Silicon

Issue description

With animation compression the animation glitches and jumps at certain points. With animation optimization done it does not.

https://github.com/user-attachments/assets/c0aaf8e3-3ab6-4b0e-843b-1dd4bfe02b27

Steps to reproduce

  1. Open project
  2. Disable animation optimization.
  3. Switch import to animation compression enabled
  4. Scrub the animation timeline and you will see near 6.1 s the animation flips.

Minimal reproduction project (MRP)

animation-compression-game-project.zip

From @Malcolmnixon

fire commented 2 months ago

@TokageItLab @lyuma if you have any ideas

TokageItLab commented 2 months ago

Just a guess, but the compression converts rotation to axis angle, so the ambiguity may be causing problems when the next angles are around 180 or 360 degrees. Or there may be simply a problem with the compressed color <-> Vector3 conversion; Since the Vector3 and float data are separated, the combination of the two may have been mismatched during the conversion.

fire commented 2 months ago

Any idea how to solve? Can we directly get axis without ambiguity?

TokageItLab commented 2 months ago

I confirmed that changing the page size value from 8kb will change where the glitching occurs, so I think there is some problem with the data page boundaries.

void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tolerance) {
...
            uint32_t key_frame = double(track_get_key_time(uncomp_track, time_tracks[i].key_index)) / frame_len;
...

The way this key_frame is obtained is a bit stinky, I have tried changing it to round or ceil, then the rotation is no longer broken, but cause stutters instead. Even if this line is not relevant, I would expect some kind of boundary error to be lurking.

fire commented 1 month ago

Do you think running a cubic / slerp interpolation between the end and the start will work

Investigating truncation of time

fire commented 1 month ago

There is definitely still work to be done, but IMO the stutter still looks better than the glitch, so I think it is acceptable to merge this PR and postpone the work to eliminate the stutter in the later.

From tokage