[SOLVED] Rotating joints with SkinningControl on a .j3o model fails

First of all, I am a total beginner to jMonkeyEngine and Java, just to let you know…

I am trying to figure out how I can implement a rigged j3o model (converted from Mixamo) into my Android app, and apply rotations manually using quaternions to certain joints. However, I am struggling with the correct procedure. With the following code, I can succesfully import and view the ybot.j3o model, however I cannot seem to define the bone correctly and rotate it. Can you help me?

        Spatial ybot = (Node) assetManager.loadModel("assets/Models/ybot.j3o");
        rootNode.attachChild(ybot);
        SkinningControl sc = ybot.getControl(SkinningControl.class);
        Node n = sc.getAttachmentsNode("mixamorig:RightForeArm");
        n.setLocalRotation(new Quaternion(0.9f, 0.9f, 0.9f, 0.9f));

When I run the code, I get this error message:

java.lang.NullPointerException: Attempt to invoke virtual method 'com.jme3.scene.Node com.jme3.anim.SkinningControl.getAttachmentsNode(java.lang.String)' on a null object reference

The structure of ybot.j3o in jMonkeyEngine SDK is:
Root Scene
-Armature
–Alpha_surface
–Alpha_Joints
–AnimComposer
—Idle
–Armature
—mixamorig:Hips
----mixamorig:LeftUpLeg
----etc…

1 Like

Hi,

Welcome to JME comunity!

AttachmentsNode is not what you are looking for. You should get the joint and apply the rotation to the joint, not the AttachmentsNode. AttachmentsNode is meant to be used for attaching items to joints so it will move by joint. (e.g. attaching a sword to hand,…)

Regards

2 Likes

Thanks! and thanks for the quick reply!

So instead I should do something like:

Joint n = sc.getArmature().getJoint("mixamorig:RightForeArm");

When I do this, I get the following:

java.lang.NullPointerException: Attempt to invoke virtual method 'com.jme3.anim.Armature com.jme3.anim.SkinningControl.getArmature()' on a null object reference

Or is there another way to call the joint?

Regards

SkinningControl sc = ybot.getControl(SkinningControl.class);

Seems SkinningControl sc is null at this line. SkinningControl might be on a sub-node of ybot.

Use something like this to get SkinningControl:

protected static Spatial findAnimRoot(Spatial s) {
        if (s.getControl(SkinningControl.class) != null) {
            return s;
        }
        if (s instanceof Node) {
            for (Spatial child : ((Node) s).getChildren()) {
                Spatial result = findAnimRoot(child);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

and call it like this:

SkinningControl sc = findAnimRoot(ybot).getControl(SkinningControl.class);

By the way, how did you convert “ybot” to j3o? From a Gltf file?

1 Like

Thanks, we are getting closer. Now the code runs and the forearm rotates correctly. But the child bones now look a little weird. Maybe they all rotated?

Yes, but it was converted from original .fbx to .gltf in blender and then in jMonkeySDK i just used the “Import model” function to convert it.

1 Like

That’s strange! I can’t tell why. Are you sure you are just rotating the ForeArm and not moving other joints?

Also, does it rotate fine in the blender?

1 Like

I am not a math genius… I think it happens because my test quaternion “new Quaternion(0.9f, 0.9f, 0.9f, 0.9f)” is not a realistic quaternion… When I try with e.g. “new Quaternion(0.00f, -0.98f, 0.14f, 0.00f)” it works brilliantly!

Thanks so much for help, it is really appreciated!

Do I mark this as solved in the title or?

Best regards

2 Likes

Glad it worked!

Yes please add [SOLVED] in the title.

Regards

2 Likes