Skip to content

Model Animation bug #47

Closed
Closed
@nuclearshadow

Description

@nuclearshadow

Loading 3D skeletal animation or updating model with said animation doesn't seem to work properly. I have tried almost identical pieces of code for both python and the Zig binding for raylib. It works correctly for the zig version.

Here's the comparison:

Python

Screenshot

animation_python

Code

import raylibpy as rl

def main():
    width = 800
    height = 600
    rl.init_window(width, height, "Model animation test")
    rl.set_target_fps(60)

    camera = rl.Camera(
        position = rl.Vector3( x = 0, y = 5, z = 15 ),
        target = rl.Vector3( x = 0, y = 0, z = 0 ),
        up = rl.Vector3( x = 0, y = 1, z = 0 ),
        fovy = 45,
        projection = rl.CAMERA_PERSPECTIVE
    )

    modelPath = "resources/3d_models/avatar_rigged.glb"

    model = rl.load_model(modelPath)
    
    animCount = 0
    anims = rl.load_model_animations(modelPath, animCount)
    for anim in anims:
        print("%s" % anim.name)

    anim = anims[0]
    print(f"{anim}")

    frameCounter = 0

    while not rl.window_should_close():
        rl.begin_drawing()
        rl.clear_background(rl.RAYWHITE)

        rl.update_model_animation(model, anim, 0)
        # rl.update_model_animation(model, anim, frameCounter)
        frameCounter = (frameCounter + 1) % anim.frame_count

        rl.begin_mode3d(camera)

        rl.draw_model_ex(model, rl.vector3_zero(), rl.Vector3(1, 0, 0), 0, rl.Vector3(1, 1, 1), rl.WHITE)
        
        rl.end_mode3d()
        
        rl.end_drawing()
    
    model.unload()
    rl.close_window()

if __name__ == '__main__':
    main()

Zig

Screenshot

animation_zig

Code

const std = @import("std");
const rl = @import("raylib");

pub fn main() !void {
    const width = 800;
    const height = 600;
    rl.initWindow(width, height, "Model animation test");
    defer rl.closeWindow();
    rl.setTargetFPS(60);

    var camera = rl.Camera{
        .position = .{ .x = 0, .y = 5, .z = 15 },
        .target = .{ .x = 0, .y = 0, .z = 0 },
        .up = .{ .x = 0, .y = 1, .z = 0 },
        .fovy = 45,
        .projection = .camera_perspective,
    };

    const modelPath = "../resources/3d_models/avatar_rigged.glb";

    var model = rl.loadModel(modelPath);
    defer model.unload();

    const anims = try rl.loadModelAnimations(modelPath);
    for (anims) |anim| {
        std.debug.print("{s}\n", .{anim.name});
    }

    const anim = anims[0];
    std.debug.print("{any}", .{anim});

    var frameCounter: c_int = 0;

    while (!rl.windowShouldClose()) {
        rl.beginDrawing();
        rl.clearBackground(rl.Color.ray_white);

        rl.updateModelAnimation(model, anim, 0);
        // rl.updateModelAnimation(model, anim, frameCounter);
        frameCounter = @mod(frameCounter + 1, anim.frameCount);

        camera.begin();

        model.drawEx(rl.Vector3.zero(), rl.Vector3{ .x = 1, .y = 0, .z = 0 }, 0, rl.Vector3{ .x = 1, .y = 1, .z = 1 }, rl.Color.white);

        camera.end();

        rl.endDrawing();
    }
}

It shows as expected on the zig version but breaks in the python version.

Another thing is that python version seems to load 1 less frame of animation compared to zig version
Here are the log messages for animations loading:

Python

INFO: MODEL: [resources/3d_models/avatar_rigged.glb] Loaded animation: ArmatureAction (3 frames, 0.066667s)
INFO: MODEL: [resources/3d_models/avatar_rigged.glb] Loaded animation: Armature|mixamo.com|Layer0 (3 frames, 0.066667s)

Zig

INFO: MODEL: [../resources/3d_models/avatar_rigged.glb] Loaded animation: ArmatureAction (4 frames, 0.066667s)
INFO: MODEL: [../resources/3d_models/avatar_rigged.glb] Loaded animation: Armature|mixamo.com|Layer0 (4 frames, 0.066667s)

And from my testing with 2 different animations, this only occurred when I used an animation with duplicate or hold keyframes in animation (in blender, don't how gltf stores animation. The animation in the screenshot only has 1 keyframe for the pose at the very beginning and another duplicate keyframe in blender) but not for an animation where every keyframe is unique (again, in blender) for the animation I downloaded from mixamo. I don't know how helpful this bit of information is.

I think the combination of 1 less frame and duplicate keyframes appears to cause this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions