raysan5 / raylib

A simple and easy-to-use library to enjoy videogames programming
http://www.raylib.com
zlib License
22.6k stars 2.27k forks source link

[module] glb animation import uses odd framerate as basis for time to frame conversion. #4472

Open aeaeaeaeaeae opened 4 days ago

aeaeaeaeaeae commented 4 days ago

Issue description

Model animation .glb exported at 60fps will not get matching frames when loaded into raylib. This is because raylib uses an odd conversion factor when translating from time to frame during load. For longer animation sequences this become significant, at 1350 frames my animation was 27 frames shorter than it was supposed to be. I guess it's a bug, unless theres a special reason for using 58.8235fps as import basis.

// rmodel.c
#define GLTF_ANIMDELAY 17    // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms)
static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount)
{
...
animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1;
animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *));
...
float time = ((float) j*GLTF_ANIMDELAY)/1000.0f;
}

Not sure if it's implemented like this for a reason, but wouldn't it be alot simpler to just use 60fps as a base instead?

const float GLTF_FRAMERATE  = 60.0f;

animations[i].frameCount = (int)(animDuration*GLTF_FRAMERATE) + 1;
animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *));

float time = j*(1.0/GLTF_FRAMERATE);
raysan5 commented 2 days ago

@aeaeaeaeaeae Could this issue be a duplicate of https://github.com/raysan5/raylib/issues/4426?

aeaeaeaeaeae commented 2 days ago

Similar topic but not duplicate. The current framerate approximation 1000/17.0 is not equal to any standard framerate, which means that the imported frame number won't match the source animation. It's better to have it a 60fps.

Changing the model animation system to interpolated time would mask the issue somewhat, though I would still prefer to have frames numbers that match the source material. Animators deal in frames, the UI of animation software deals with frames and having exact frame numbers makes managing animation data between the editor and the code a lot simpler.

I'm not sure if framerates are encoded in .glb files, if so using that value would probably be the cleanes solution it terms frame generation, as this would support animation running at various framerates 24fps, 25pfs etc. Having discreet frames is okey imo, I suspect skeleton interpolation to be complicated, and managing the playback rate is easy using deltatime.