Issue with multiple models and Morph animations

Hi,
I’ve found some strange behavior while testing the new morph animations. It seems that when I load 2 instances of the same model, only one of them plays the animation correctly. (And both work correctly on their own).
I’ve reduced it to a test case:

package base;
import com.jme3.anim.AnimComposer;
import com.jme3.anim.MorphControl;
import com.jme3.app.ChaseCameraAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

public class TestMorph extends SimpleApplication {

    Spatial model=null;
    AnimComposer animComposer=null;

    Spatial model2=null;
    AnimComposer animComposer2=null;
    public static void main(String... args) {
        TestMorph app = new TestMorph();
        app.start();
    }
    public TestMorph(){
        setShowSettings(false);
    }

    @Override
    public void simpleInitApp() {

        //first model
        model = assetManager.loadModel("models/test/testMorph.j3o");
        rootNode.attachChild(model);
        Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        model.setMaterial(m);
        model.setLocalTranslation(2, -2.5f, 0);
        model.setLocalScale(1.f);
        Spatial child = ((Node) ((Node) model).getChild(0)).getChild(0);

        animComposer = child.getControl(AnimComposer.class);
        animComposer.setEnabled(true);
        child.getControl(MorphControl.class).setEnabled(true);

        //second model
        model2 = assetManager.loadModel("models/test/testMorph.j3o");
        rootNode.attachChild(model2);
        Material m2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        m2.setColor("Color",ColorRGBA.Blue);
        model2.setMaterial(m2);
        model2.setLocalTranslation(-2, -2.5f, 0);
        model2.setLocalScale(1.f);
        Spatial child2 = ((Node) ((Node) model2).getChild(0)).getChild(0);

        animComposer2 = child2.getControl(AnimComposer.class);
        animComposer2.setEnabled(true);
        child2.getControl(MorphControl.class).setEnabled(true);





        //basic controls
        ChaseCameraAppState chase = new ChaseCameraAppState();
        chase.setTarget(rootNode);
        getStateManager().attach(chase);
        flyCam.setEnabled(false);
        inputManager.addMapping("morphUp", new KeyTrigger(KeyInput.KEY_I));
        inputManager.addMapping("morphDown", new KeyTrigger(KeyInput.KEY_U));
        inputManager.addListener(new AnalogListener() {
            @Override
            public void onAnalog(String name, float value, float tpf) {
                if (name.equals("morphUp")) {
                    animComposer.setCurrentAction("Action_MT");
                    animComposer.setTime(AnimComposer.DEFAULT_LAYER,0.5f);

                    animComposer2.setCurrentAction("Action_MT");
                    animComposer2.setTime(AnimComposer.DEFAULT_LAYER,0.5f);

                }
            }
        }, "morphUp", "morphDown");
    }
}

The model “testMorph” is a basic cube I did on blender, and exported it via gltf to j3o. The morph animation is just moving 2 corners out.
With both objects I get this,
image

While with each one on their own I get this:
image
image
and both work just fine.
Am I doing something wrong here? I actually haven’t found any test for loading morph anims from a model, so maybe I’m missing something. For example it’s odd that both the AnimComposer and MorphControl are not enabled by default.

EDIT: It wasn’t super clear in the original post, but the issue here is that only ONE of the 2 models is actually playing the animation

1 Like

Hmm, seems to be a cloning issue with MorphControl.

It does not override cloneFields()!

Can you please add this code into MorphControl class and see if that fixes the issue?

@Override
public Object jmeClone() {
    return super.jmeClone();
}

@Override
public void cloneFields(Cloner cloner, Object original) {
    super.cloneFields(cloner, original);

    this.targets = new SafeArrayList<>(Geometry.class);
    this.targetLocator = new TargetLocator();
}
2 Likes

There are a number of issues with MorphControl. Looks like another case of unfinished coding. I’ve opened issue 1458.

1 Like

Okay so with the fix here : test case and solution for issue #1548 (MorphControl doesn't override methods) by stephengold · Pull Request #1549 · jMonkeyEngine/jmonkeyengine · GitHub
My 2 models do their animations properly, Thanks !
Is there a way to workaround this issue while waiting its integration ? Would I be able to change the MorphControl (replacing it with one with the clone fix) inside the loaded model for example?

1 Like

@sgold thank you so much for the fix :slightly_smiling_face:

1 Like

Is there a way to workaround this issue while waiting its integration ? Would I be able to change the MorphControl (replacing it with one with the clone fix) inside the loaded model for example?

I don’t think that would work unless you were also using an Engine with the fix.

I plan to integrate the fix and release v3.4.0-beta4 in a few days. It’s up to you whether or not you want to wait that long.

I plan to integrate the fix and release v3.4.0-beta4 in a few days. It’s up to you whether or not you want to wait that long.

Oh ok, I’ll wait then. Again, Thanks for your help.

1 Like

JMonkeyEngine v3.4.0-beta4 has been released. I hope that works for you.

1 Like