VertexAnimationBaker with glb files

I’m following this playground: https://playground.babylonjs.com/#CP2RN9#18. It imports a .babylon file, and uses hardcoded animation ranges. I’m trying to get it work with an arbitrary .glb file.

The problem is that baker.bakeVertexData hangs. It’s because the onAnimationEnd is never called (by Animatable._raiseOnAnimationEnd), so the promise never completes. I.e. the mesh has no animatables.

I suspect it’s because the animationGroups in the .glb are targeting the __root__ mesh, whereas I’m baking the actual character mesh inside it. The root mesh has no geometry though, so we can’t bake that. But the actual mesh has no animations. What to do?

For context, here’s what the asset container hierarchy looks like:

    meshes: [
        0:__root__
            animations: []
            getAnimationRanges(): []
        1:npc2
            parent: __root__
            skeleton
                getAnimatables(): (26)
                getAnimationRanges(): []
            animations: []
            getAnimationRanges(): []
    ]
    animationGroups: [
        {
            name: 'npc2.idle',
            animatables: (75)
            targetedAnimations: (75)
        },
        {...}
    ]

I’ve tried detaching the npc2 mesh from root and disposing it, but that stops animations from working. Somehow animations are associated with root, even though their targets are bones (which are attached the skeleton, which is attached to npc2, not root.

@brunobg @Evgeni_Popov Any ideas?

It seems it’s an open problem:

I don’t know if @Andi has made progress on this(?)

Unfortunately I haven’t worked on this anymore, the last working solution was the one described in my post, basically “baking” the animations Blender and exporting a .babylon file. In blender you need to use only one action track and add all animation keys sequentially.

Apologies if the explanation if not according to the issue described.

That sounds like a reasonable solution. Alternatively, maybe we can create skeleton animations from the animationGroups.

So, I’m trying to move the animatables from the animationGroups into the skeleton’s animatables. From looking at the VATManager with instances PG, skeleton.getAnimatables() needs to contain all animations in a single list, but I don’t understand how to generate the hierarchy.

Skeleton.getAnimatables() contains Bones.
AnimationGroup has targetedAnimations. An Animation has getKeys and ranges. How do you create a Bone from an AnimationKey? And which parent should it go under?

Hi @alekop just checking in if you still need help with this?

Thanks for following up! I hit a wall on this and moved to other tasks, but I’m coming back to it. I’m not sure how to proceed…

It seems that animation baker needs the animations to be in the skeleton, not in animationGroups. So I’m trying to iterate over assetContainer.animationGroups, create an Animation object from each one, and add it to the correct animatable (bone) in the skeleton. Does that sound like the right direction?

I’ll tag @PatrickRyan on this as he has been experimenting with skeletal animations a lot and is certainly way better than me at this :rofl:

@carolhmj and @alekop, I’m not sure how much help I can be because it sounds like there is an issue with baking animation groups to vertex. I don’t know if it’s even possible to recreate an animation from an animation group in code because a group is a collection of animations that all play at once. You can see the individual animations if you log the animatables. For example, this is one animation playing on the hips bone of an animated character as logged from the animation group:

image

But you can’t clone this animation from the group. This would be the only way I would think that you could duplicate each animation to be a separate scene-level animation. But I think the core problem here is that there is an incompatibility with vertex baking and glTF which loads with skeletal animations in an animation group. If using the .babylon format, you don’t get an automatic grouping of animations.

But I am also want to clarify one concept from a previous post.

The animation group is a collection of animations that play together. The animation group will run an animation curve on an animatable, which in the case of a skeleton is a bone. So you are already targeting a bone in skeletal animation with the data from the animation group. It’s just that the animation exists as a part of a group rather than a stand-alone animation. In the case of skeletal animation this makes sense as playing animations on isolated bones would not be particularly useful as the motion of each bone is augmented by the parent structure’s movement so no individual animation on a single bone is enough by itself.

It seems, at the moment, that Andi’s explanation above is the best workaround at the moment.

I went with Andi’s approach and switched to .babylon files, with a single animation track. I wrote a simple baker tool that lets me type in the animation ranges manually, then bake and export to JSON. Loading VATs from JSON is faster than baking anyway.

But… For the purpose of baking, it may not be necessary to do any animation conversion at all. The baker works by capturing vertex positions and recording them in a texture. This glosses over a lot details, but I believe that’s the general idea. So as long as you can animate the skeleton, it shouldn’t matter how.

Right now the baker is responsible for the animation, so it has an opinion about it. But maybe it can be modified to use a “nextFrame” callback to let the caller do the animation logic instead. This way, the baker would just capture, and be animation-method-agnostic. That would allow baking all kinds of animations… Even ones created on the fly, e.g. by dragging bones with the mouse.

1 Like