Problem with automatic ragdoll shape generation using JBullet

Hello everyone,

I’m reposting the question from Stackexchange here, because it hasn’t got enough attention, and I thought that maybe you guys will be able to help :slight_smile:

Anyway, I’m trying to automatically generate ragdoll colliders (for now, box colliders) from my mesh.

First of all, I specify the body parts like so:

        ragdoll.setRagdollBone(Ragdoll.RagdollBodyPart.HEAD, "Bip01 Head");
        ragdoll.setRagdollBone(Ragdoll.RagdollBodyPart.LEFT_UPPER_ARM, "Bip01 L UpperArm");
        ragdoll.setRagdollBone(Ragdoll.RagdollBodyPart.LEFT_ELBOW, "Bip01 L Forearm");
        ragdoll.setRagdollBone(Ragdoll.RagdollBodyPart.RIGHT_UPPER_ARM, "Bip01 R UpperArm");
        ...

Secondly, for each configured body part, I find the bone in my skeleton, get all vertices that are influenced by it and construct an AABB from the vertices multiplied by the bone’s local matrix:

private BoxShape createBoxShapeForBone(final Bone a) {
    final List<Vector3f> influencingVerticesForBone = this.getInfluencingVerticesForBone(a);
    final SimpleAABB aabb = new SimpleAABB();

    final TempVars tempVars = TempVars.get();

    for (Vector3f boneVertex : influencingVerticesForBone) {
        aabb.expand(a.getLocalBindMatrix().transformPosition(boneVertex, tempVars.vect3d1));
    }
    final Vector3f extents = aabb.getExtents(tempVars.vect3d1);
    final BoxShape boxShape = new BoxShape(Utils.convert(tempVars.vecmathVect3d1, extents));

    tempVars.release();
    return boxShape;
}

Next, I call setLocalScaling() on the generated box shape with the bone’s world matrix scale, and set the rigidbody’s transform to the bone’s world matrix with scaling removed:


private void getMatrixForBone(final Matrix4f out, final Bone bone) {
    final TempVars vars = TempVars.get();

    final Vector3f bonePos = bone.getWorldBindMatrix().getTranslation(vars.vect3d2);
    final Quaternionf boneRot = vars.quat1.set(bone.getWorldBindMatrix().getRotation(vars.axisAngle4f1));

    Utils.fromRotationTranslationScale(out, boneRot, bonePos, Utils.IDENTITY_VECTOR);
    vars.release();
}

private void createBoneCollider(final Bone bone, final TempVars vars) {
    BoxShape boxShape = this.createBoxShapeForBone(bone);
    boxShape.setLocalScaling(Utils.convert(vars.vecmathVect3d1, a.getWorldBindMatrix().getScale(vars.vect3d1)));
    boxShape.setMargin(0.0f);
    this.getMatrixForBone(vars.tempMat4x41, bone);
    final RigidBody rigidBody = this.createRigidBody(1.0f, boxShape, vars.tempMat4x41);
    ...
}

The result I’m getting is a really flat box for the head bone (attached an image, please ignore missing bones for the hands and feet in the outline):

Do you happen to know where the problem is? Also, if you know of any alternative approach, I’d be glad to hear about it.

Thank you,
Patryk