2
votes

I use libgdx for rendering 3d models. First of all I load my model from assets:

assetManager.load(name, Model.class);
assetManager.finishLoading();
Model model = assets.get(name, Model.class)

My model comes with one idle animation. Next time I create animation controller and start rendering model with animation.

ModelInstance modelInstance = new ModelInstance(model);
AnimationController controller = new AnimationController(modelInstance);   
controller.setAnimation(modelInstance.animations.first().id, -1);

render method

controller.update(Gdx.graphics.getDeltaTime());
modelBatch.begin(cam);
modelBatch.render(model, environment);
modelBatch.end();

It works fine, animation plays.

Problems begin when I try to load and run next animation.

assetManager.load(animation, Model.class);
assetManager.finishLoading();
Model animModel = assets.get(animation, Model.class)

modelInstance.model.animations.add(animModel.animations.first());
System.out.println("animation size "+modelInstance.model.animations.size); // prints 2

controller.setAnimation(modelInstance.model.animations.get(1).id, -1);

Then an error occurs

com.badlogic.gdx.utils.GdxRuntimeException: Unknown animation: acrobat
W/System.err: atcom.badlogic.gdx.graphics.g3d.utils.AnimationController.obtain(AnimationController.java:158)atcom.badlogic.gdx.graphics.g3d.utils.AnimationController.animate(AnimationController.java:349)
at com.badlogic.gdx.graphics.g3d.utils.AnimationController.animate(AnimationController.java:331)
at com.badlogic.gdx.graphics.g3d.utils.AnimationController.animate(AnimationController.java:303)
at com.snaappy.ar.game.MyGameRenderer$5.run(MyGameRenderer.java:768)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:488)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1562)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1262) 

It looks like that animation has not been added to ModelInstance.

Next I tried to add animation to ModelInstance directly

modelInstance.animations.add(animModel.animations.first());

instead of

modelInstance.model.animations.add(animModel.animations.first());

The error no longer appears but animation not playing.
Model has two animations but can play only the first idle animation which was originally.

This problem is solved by re-creation ModelInstance and AnimationController. Each time after loading an animation, I have to recreate those objects.

modelInstance.model.animations.add(animModel.animations.first());
ModelInstance modelInstance = new ModelInstance(modelInstance.model);
AnimationControllercontroller = new AnimationController(modelInstance);   

I think this is not good. It looks like a bug in the LibGDX.

I want to hear an expert opinion on this issue.

1
Are you able to post a small but complete working example demonstrating the problem?Ryan Stout
I think that is written in detail already.Dmitriy Puchkov
I can't run the code as you've posted it. I have used libgdx for 3d animation and I haven't encountered the same problem you are, but if I can't see your code, it's pretty hard to say what you might be doing wrong. If you showed your code it would be easier to help you debug. Anyway, good luckRyan Stout
From the code snippets you provided it looks like you are manually modifying the model instance by adding totally different items to the animations array. This ofcourse wont work. If you want to use a totally different model then just do that.Xoppa
@Xoppa I have a lot of animations in different files. This is done so that the model does not load too long. The user not need all the animations at once, he can load current animation by click. Now I move ModelInstance class to my code and a little bit change copyAnimations method and call it after new animations has been added to the model. It works fine, but is there the best way to merge animations from different files?Dmitriy Puchkov

1 Answers

0
votes

I found a better solution than create new ModelInstance each time after adding animation.
Look at my pull request to LibGDX https://github.com/libgdx/libgdx/pull/4972

Method copyAnimation will be public.

Then we can directly add it to the our ModelInstance after load new animation from assets.

assetManager.load(animation, Model.class);
assetManager.finishLoading();
Model animModel = assets.get(animation, Model.class)

modelInstance.copyAnimations(animModel.animations);