Issue weight painting from code

Hi, recently i’ve been working on reducing the amount of draw calls in my project, and one thing is to have one model for both legs and one model for two hands.

The armature structure is:

and model to be animated (only geometry is imported through blender) is:

as you can see, the orientation in blender (hence during import) is the exact same. Now, when i view the skeleton with the hands model attached under the node affected by skinning control (with some boxes attached to attachment nodes):
image
it is exactly as expected in blender.

but when i apply:

    public static void weightPaintHands(Mesh mesh, byte leftHandBoneIndex, byte rightHandBoneIndex) {
        if (leftHandBoneIndex == -1 || rightHandBoneIndex == -1) {
            return;
        }

        var posBuffer = (FloatBuffer) (mesh.getBuffer(VertexBuffer.Type.Position).getData());
        int posBufferLimit = posBuffer.limit();
        int vertexCount = posBufferLimit / 3;// by default

        int boneIndexCount = vertexCount;
        byte[] boneIndex = new byte[boneIndexCount];
        float[] boneWeight = new float[boneIndexCount];
        var temp = new Vector3f();

        for (int i = 0; i < posBufferLimit; i += 3) { // for each vertex position
            temp.set(posBuffer.get(i), posBuffer.get(i + 1), posBuffer.get(i + 2));

            var vertexIndex = i / 3;

            if (temp.getX() < 0) {
                // weight paint for right hand bone
                boneIndex[vertexIndex] = rightHandBoneIndex;
            } else {
                // weight paint for left hand bone
                boneIndex[vertexIndex] = leftHandBoneIndex;
            }
            boneWeight[vertexIndex] = 1f;

        }

        mesh.setMaxNumWeights(1);
        mesh.setBuffer(VertexBuffer.Type.BoneIndex, 1, BufferUtils.createByteBuffer(boneIndex));
        mesh.setBuffer(VertexBuffer.Type.BoneWeight, 1, BufferUtils.createFloatBuffer(boneWeight));
        mesh.setBuffer(VertexBuffer.Type.HWBoneIndex, 1, BufferUtils.createByteBuffer(boneIndex));
        mesh.setBuffer(VertexBuffer.Type.HWBoneWeight, 1, BufferUtils.createFloatBuffer(boneWeight));

        mesh.generateBindPose();
    }

the same setup shows the skeleton as:
image

now, the mesh is weight painted correctly (bones deform correct vertices), but why does invoking
mesh.generateBindPose() on hands mesh cause bones to change position/rotation in relation to parent bone?

solved:

what worked:

  1. in blender, in hands.blend
    a) add bones HandL and HandR
    b) add vertex groups (were present previously, but dont work/get imported without bones)
    c) parent bones to the hand mesh
  2. in jme scene editor
    a) delete the armature in hands.j3o
    b) attach directly to Humanoid armature
  3. in code
    a) dont use the above function :frowning:

requires a bit of work but i was banging my head against a wall for like a week now and it solves it…

1 Like