Way to go with the BABYLON.SceneLoader.ImportAnimationsAsync (in comparation with BABYLON.SceneLoader.ImportMeshAsync)

Hi there:

In our projects, we have a workflow where the 3D Artist generates GLTF/GLB files with two different contents:

  • mesh files;
  • animation files of such meshes.

Until now, we’re being using BABYLON.SceneLoader.ImportMeshAsync to load those animations-only assets, but we are certainly a little picky and think maybe BABYLON.SceneLoader.ImporAnimationsAsync is a more semantic and proper way to make the job.

This said, We are able of course to load properly the animations with ImporAnimationsAsync, but once the different animation groups are created under the scene, animationGroups[i].targetedAnimations[j].target is always null, when formerly (I mean using ImportMeshAsync) we had always a valid value there. With target being null for all the targetedAnimations it’s not possible to assign the animations to the geometry nodes in the scene.

Any advice on that?

Thanks for your time.

I didn’t write this part of the code, so I don’t know for sure, but it looks like ImportAnimations has a targetConverter callback that allow you to assign the target. Are you passing in this callback?

oh sorry @bghgary I thought you wrote it :slight_smile:

Hi @bghgary (and @sebavan btw):

Well, using in my code the let’s call it: " ImportMeshAsync schema", I have something like this:

BABYLON.SceneLoader.ImportMeshAsync("", filename+".gltf");
    .then(function (result) {
        _engine.hideLoadingUI();
        //
        assignAnimations(result.animationGroups)
    })
    .catch(function (error) {
        console.error(_TAG + error);
    }

…as you can see, I process (assign) the scene.animationGroups this way:


function _assignAnimations(animationGroups) {
  for (var i = 0; i < animationGroups.length; i++) {
    animationGroups[i].stop();
    for (var j = 0; j < animationGroups[i].targetedAnimations.length; j++) {
	  animationGroups[i].targetedAnimations[j].target =_scene.getNodeByName(animationGroups[i].targetedAnimations[j].target.name);
    }
  }
}

As said, that works flawless.

Going now to implement the same functionality by means of ImportAnimationAsync, I see that:

  • there’s not result.animationGroups anymore, and instead I need now to use scene.animationGroups;

  • following your clues, I must provide the aforementioned assignAnimations method as the 6th parameter of the call, isn’t it?.

Well, the case is that I’m trying all that in my own code, but it’s not working at all, because as I stated in my question, animationGroups[i].targetedAnimations[j].target is always null.

Maybe an existent PG would help, but I’couldn’t find none.

Thanks for your time.

Let me add @Deltakosh to the thread as he is the true king of Babylon and might have more clues :slight_smile:

Yup it is where you could convert the target to your own need, were you able to try smthg like:

(target) => _scene.getNodeByName(target.name)

When empty it is actually what the code would try to do normally :frowning:

A repro would really help us fix it faster here.

Hi there, @sebavan:

As always, your help is really appreciated.

In the absence of an existing PG on this subject (at least I haven’t found one), I will try to generate one by my own, as suggested.

Thanks for your time.

1 Like

Are the node names from the animations already loaded? If not, this is expected as you are only loading the animations and not the node they point to. The default behavior is to find the node by name in the scene, but if there are not there, they will be null.

targetConverter defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)

1 Like

Hi @bghgary:

Good point, indeed. That could be the reason. I’ll check it as soon as possible.

Best regards.