[SOLVED] Model breaks when exporting with AnimComposer / SkinningControl

Hi,

I wanted to give the new AnimComposer a try, and I noticed that after running the AnimMigrationUtils.migrate(model)method and saving it, the model ‘breaks’.

The weird thing is, that when you actually play an animation on the broken model, it assembles itself again correct.

This is probably a weird explanation, so I added some screenshots and a test case:

public class AnimComposerErrorTest extends SimpleApplication {

    public static void main(String[] args) {
        new AnimComposerErrorTest().start();
    }

    @Override
    @SneakyThrows
    public void simpleInitApp() {
        Spatial model = assetManager.loadModel("/Models/characters/human/human-all-rigged.j3o");
        AnimMigrationUtils.migrate(model);

        BinaryExporter exporter = BinaryExporter.getInstance();
        exporter.save(model, new File(JmeSystem.getStorageFolder(), "migrated-model.j3o"));

        assetManager.registerLocator(JmeSystem.getStorageFolder().getAbsolutePath(), FileLocator.class);
        Spatial migratedModel = assetManager.loadModel("migrated-model.j3o");

        model.move(-2, 0, 0);
        //SpatialUtils.getFirstControl(model, AnimComposer.class).ifPresent(animComposer -> animComposer.setCurrentAction("idle"));

        migratedModel.move(2, 0, 0);
        //SpatialUtils.getFirstControl(migratedModel, AnimComposer.class).ifPresent(animComposer -> animComposer.setCurrentAction("idle"));

        rootNode.attachChild(model);
        rootNode.attachChild(migratedModel);

        rootNode.addLight(new AmbientLight(ColorRGBA.White.mult(0.3f)));
        rootNode.addLight(new DirectionalLight(Vector3f.UNIT_Y.negate(), ColorRGBA.White));
    }
}

result:
Imgur

But when I uncomment the lines that start playing an animation it becomes:
Imgur

The SpatialUtils.getFirstControl() method only does a depth first traversal of the spatial and returns the first control that matches the given type, so no ‘magic’ happens in that method.

Make suer to add this before exporting original model:

 SkinningControl sk = originalModel.getControl(SkinningControl.class);
 sk.getArmature().saveInitialPose();

or do this on migratedModel :

SkinningControl sk = migratedModel.getControl(SkinningControl.class);
sk.getArmature().applyBindPose();
2 Likes

this character preferred to be in egg transform :rofl: he packed himself very good!

3 Likes

Thanks @Ali_RS, that worked!

Could you explain me the difference between bindPose and initialPose?

I think other folks can explain it more better. :slightly_smiling_face:

Based on what java doc says:

Bind Pose (T-Pose)

I believe bind pose is the state of the model when no animation is applied: all bone/joint transforms set to identity, no morphs applied, and so on. Bind pose might be a T pose or a Y pose or something else entirely, depending on how the model was created.

As the documentation says, initial pose is the state when the model is loaded from assets.

In JME 3.2, bind pose and initial pose were always the same. I’m unsure why @nehon created the distinction.

2 Likes

Ok, thanks. I indeed didn’t get the difference between bind pose and initial pose.

1 Like