JME 3.3 AnimClip Sharing

Hi o/

I’m upgrading some of my AssetLoaders to use the new com.jme3.anim package.

I’ve run into a snag. The new TransformTrack constructor takes in reference to a Joint object. The old BoneTrack took in the integer ID of the bone.

So my question is: Do I have to instantiate a new AnimClip/TransformTracks for each Armature, since TransformTrack uses a direct reference to a Joint object?

I have models and animations in separate files. I want to reuse the animations multiple times. So I would like to apply an AnimClip on multiple meshes. Its safe to assume that the meshes contain the same armature blend indices and weights.

Yes, you need to instantiate a new AnimClip and TransformTrack.
Not sure why @Nehon designed it like this in the new animation system.

an example code for retargeting an AnimClip from one model to another model supposing both have the same rig :

        Spatial model = assetManager.loadModel("models/character/model-1/model.gltf");
        AnimComposer ac = getAnimComposer(model);
        AnimClip clip = ac.getAnimClip("walk");
        rootNode.attachChild(model);

        model = assetManager.loadModel("models/character/model-3/model.gltf");
        ac = getAnimComposer(model);
        SkinningControl sc = ac.getSpatial().getControl(SkinningControl.class);

        SafeArrayList<AnimTrack> tracks = new SafeArrayList<>(AnimTrack.class);
        for (AnimTrack track : clip.getTracks()) {
            TransformTrack tt = (TransformTrack) track;
            HasLocalTransform target = null;

            if (tt.getTarget() instanceof Node) {
                target = getAnimRoot(model);
            } else if (tt.getTarget() instanceof Joint) {
                Joint joint = (Joint) tt.getTarget();
                target  = sc.getArmature().getJoint(joint.getName());
            }

            TransformTrack newTrack = new TransformTrack(target, tt.getTimes(), tt.getTranslations(), tt.getRotations(), tt.getScales());
            tracks.add(newTrack);
        }

        clip = new AnimClip("walk");
        clip.setTracks(tracks.getArray());
        ac.addAnimClip(clip);
        ac.setCurrentAction("walk");
        model.move(2, 0, 0);
        rootNode.attachChild(model);

Maybe we can introduce a new constructor and getter/setter for directly setting :

CompactVector3Array translations,
CompactQuaternionArray rotations,
CompactVector3Array scales

in TransformTrack:

so that we can directly share the compact translation, rotation, scales between Tracks without unpacking /repacking them. @pspeed, @sgold any thought?

Edit:
Okay, never mind. Using TransformTrack.jmeClone() does already share those compact transforms and times. We just need to reset the target to reference new Joint after cloneing. Sorry for my ignorance :wink:

1 Like

Ahh, thanks!!

1 Like

You are welcome. :slightly_smiling_face:
If you had any other questions/problems with the new animation system feel free to ask, I will be glad to help.