How to add clothing to character model

Apply- not work :frowning:

I made a quick video showing how I do it in jme’s SDK so its easier to see what’s going on. But the same works at run-time with the code I posted above

I also convert my models from gltf/glb → j3o before working with them in the engine, so that allows me to edit them in the SDK’s scene composer like this. I actually didn’t even know it worked to load GLB at run-time, but in my case I still always convert to .j3o. Converting to j3o is as simlple as double-clicking (or right-click → convert) a gltf or glb file in the SDK.

4 Likes

thansk
can you test my model?

And how to expot glb without armature?

I think if you put the boots in their own .blend file and delete the animControl and bones in blender, then it should have no armature in jme. I would still suggets converting to j3o so you could view the base character model in the SDK and see if the Armature is potentially attached deeper than the scene’s rootNode, which could also be the problem. And then you can also delete the armature in the boots’ .j3o file too.

I have error with viewer (Open gl not started)

The boots.blend file seems to have lost the vertex groups data when I open it in Blender. Could you send over a version of the character with boots in .glb format instead?

1 Like

It looks like the boots also have no vertex groups. I manually assigned them since they matched each foot bone, and then I managed to get things working.

The export process from blender is a bit finicky, and I didn’t include that part in my video since I hadn’t done it in so long and forgot the details.

However, it appears as though I needed to export the boots from blender WITH the armature, and then in the SDK I removed the Armature and AnimComposer from the .j3o file of the boots, then attached that to the base character and it worked.

So it looks like you need to use the scene composer to edit the boots model in JME, or if the scene composer is not working you could probably also remove the Armature and AnimComposer from the boots with code before you attach the boots.

In my blender model boots have vertex goups.
How to export to glb with wertex groups?
How to delete Armature and AnimComposer in code?

As long as the boots have vertex groups and the same Armature as the character model in blender, then it is ready for export to .glb.

the Spatial object has a removeControl(Class controlClass) method, so if you call this for the boots’ Armature and AnimComposer before you attach it to the character model, then I suspect it should work the same as deleting them in the SceneComposer like I did.

1 Like
character = assetManager.loadModel("Models/char.glb");
        character.setLocalTranslation(1.2311511f, -0.5f, 6.1211777f);
        character.setLocalScale(0.15f);
        character.rotate(0, -1.7f, 0);
        
        //AnimComposer animComposer = character.getControl(AnimComposer.class);
       // animComposer.setCurrentAction("run");
       Node charNode = (Node)character;
       Node charArmature = (Node)charNode.getChild("Armature");
       
       
        Spatial boots = assetManager.loadModel("Models/boots.glb");
        boots.removeControl(AnimComposer.class);

        Node bootsNode = (Node)boots;
        
        //bootsNode.detachChildNamed("Armature");
        boots = (Spatial)bootsNode;
        
        charNode.attachChild(boots);
        
        rootNode.attachChild(character);

if i detach armature
bootsNode.detachChildNamed("Armature");

boots go missing

If the boots go missing, maybe try calling setLocation(0,0,0) on them after you detach both controls and before attaching to the character.

Otherwise it might be worthwhile to figure out if you can get the scene composer to work and then convert these to .j3o file and work with them in the SDK since I know that can work. Otherwise I’m just guessing how to get it to work with code at run-time since I personally set up individual clothing pieces in the scene composer.

I also suggest converting to .j3o and loading models as .j3o instead of glb because it will reduce the overall size of your app’s assets folder once the app is distributed, since .glb includes extra data that is useless to an engine and is excluded from the .j3o version. You may also have better luck opening a .j3o file in the scene composer as opposed to a .glb

1 Like

how to manually assigned ?


I delete animcomposer and when i open model it ignites again? how to delete and save
can’t delete armature from model

Armature is handled by SkinningControl. I think you need to remove the control.

boots.removeControl(SkinningControl.class);
1 Like

character = assetManager.loadModel("Models/char.glb");
        character.setLocalTranslation(1.2311511f, -0.5f, 6.1211777f);
        character.setLocalScale(0.15f);
        character.rotate(0, -1.7f, 0);
        
        //AnimComposer animComposer = character.getControl(AnimComposer.class);
       // animComposer.setCurrentAction("run");
       Node charNode = (Node)character;
       Node charArmature = (Node)charNode.getChild("Armature");
       
       
        Spatial boots = assetManager.loadModel("Models/boots.glb");
        boots.removeControl(AnimComposer.class);
        boots.removeControl(SkinningControl.class);
        
        Node bootsNode = (Node)boots;
        
        boots = (Spatial)bootsNode;
        charNode.attachChild(boots);
        
        rootNode.attachChild(character);

nothing changed

The SDK doesn’t let you delete the Armature for some reason (likely a bug). It worked for me to delete the AnimComposer but not the Armature.

So to get rid of both controls, move just the Geometry to its own node and delete the node that contains the Armature and AnimComposer. So you will be left with only the Geometry named “1.Body.001” in the scene.

I’m also not sure if it is even possible able to edit and re-save a model in .glb format. Never tried, but the fact that you say the AnimComposer re-appeared after you deleted it makes me believe that the .glb “viewer” is only just that: a viewer.

In which case you should double-click your .glb files in the SDK to convert to .j3o and edit them in that format instead. Working with files in .j3o format is practically the same as .glb but way better in JME.

I spent more time working on attaching clothing with code dynamically at run-time (as opposed to doing it in the SDK like I was in the video I made in a previous reply) and it appears it’s not nearly as easy as I was expecting and implying.

In my video, I had to save and re-open the clothed model’s j3o file in the SDK to get the animations to register on the newly attached pieces. Apparently there is code that gets run in the SkeletonControl or AnimControl 's read method that is necessary for making the animations effect the newly attached clothing/armor.

So to get my clothing to work with animations at run-time, I had to use this code to do the following:

  1. Attach clothing to the animated model.

  2. Detach the animated model from the scene

  3. Save the animated model to a temporary file in assets folder

  4. Immediately re-load this file with assetManager (this triggers the controls’ read methods which appears to contain protected code necessary to make things work)

  5. Re-attach the newly loaded model, and clothing pieces are now animated

             Node cosmeticNode = agent.getCosmeticNode(); //node to attach clothing and other cosmetics to
             Node parentNode = cosmeticNode.getParent();
             
             cosmeticNode.attachChild(clothingSpatial);
             parentNode.detachChild(cosmeticNode);
             
             
             
             File tempSaveFile = new File("assets/tempAnimHold.j3o");
             BinaryExporter be = BinaryExporter.getInstance();
             try {                   
                 be.save(cosmeticNode, tempSaveFile);                    
             } catch (Exception ex) {                    
                 ex.printStackTrace();
             }
             
    
                 cosmeticNode = (Node) agent.getApp().getAssetManager().loadModel("tempAnimHold.j3o");
                 agent.setCosmeticNode(cosmeticNode);
                 
                 parentNode.attachChild(cosmeticNode);
    

So I would say this is a bug in the function of AnimControl or SkeletonControl, and although I have not yet tested with the same with AnimComposer and Armature, I presume it has the same issue since the new anim system only worked for me in the SDK, and was giving the OP similar troubles when doing the same with code.

Or i could be wrong that its a bug, I’m only assuming that the read methods have the code thats magically fixing things, since that appears to be the only type of initiation code that would get called on load that I can’t call directly myself. Hopefully someone with more knowledge about the animation system can provide some more insight.

1 Like

I got it to work without saving and re-loading.

It was almost as simple as removing and re-adding the SkeletonControl and AnimControl, except the SkeletonControl needs recreated based on an updated Skeleton that is generated in the AnimControl object. So this code instead:

                cosmeticNode.attachChild(clothingSpatial);
            
                cosmeticNode.removeControl(animControl);
                cosmeticNode.removeControl(skeletonControl);
                
                cosmeticNode.addControl(animControl);
                cosmeticNode.addControl(new SkeletonControl(animControl.getSkeleton()));

I’ll have to test how this translates to the new Animation system with AnimComposer, but the new Animation system also required a save/reload in the SDK to work, so i suspect it also requires some further initiation code like this at run-time.

well. I feel almost there but not quite, this does not seem super intuitive. Any more good discoveries with this
??
@yaRnMcDonuts

1 Like

Yes for the new animation system, the SkinningControl needs recreated using the existent Armature after clothing or armor is attached, similar to the way the old system required the SkeletonControl be recreated with the existent Skeleton.

I meant to post this follow up a while ago and also ask the OP if they were still having trouble or found another solution, but I was blocked from replying more since I had replied 3 times in a row with no other rplies, and it unfortunately looks like the OP hasn’t been seen in a while now. (so thank you @woodx319 for replying so I can post again lol)

But to get the animations to work, it is necessary to use this code to recreate the SkinningControl once armor/clothing has been attached (assuming the armor has proper vertex groups matching the animated model)

       Node cosmeticNode = agent.getCosmeticNode();
       SkinningControl skinningControl = ((Node) cosmeticNode).getControl(SkinningControl.class);
        
        if(skinningControl != null){
            armature = skinningControl.getArmature();
            cosmeticNode.removeControl(skinningControl);

            cosmeticNode.addControl(new SkinningControl(armature));
        }

@nnpa are you still working on this? If so then I believe this code is the final missing link that you needed to get your boots to work and follow the animations properly.

3 Likes