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

Hi, looks like you are using NiF file formats for your animations? Where do you multiply the transformations across the bone hierarchy? (ie root bone up to the head)

Hello,

No, it’s my own file format - I export geometry from 3dsmax to a JSON-based file format. :slight_smile: And when loading the mesh from file, I just do the following:

// Bone.java
    void calculateBindMatrices() {
        Utils.fromRotationTranslationScale(this.localBindMatrix, this.bindRotation, this.bindPosition, this.bindScale);
        if (this.parent == null) {
            this.worldBindMatrix.set(this.localBindMatrix);
        } else {
            this.parent.getWorldBindMatrix().mul(this.localBindMatrix, this.worldBindMatrix);
        }
        this.worldBindMatrix.invert(this.inverseBindMatrix);
    }
// Skeleton.java
    private void calculateBindMatrices(final Bone bone) {
        bone.calculateBindMatrices();

        for (Bone child : bone.getChildren()) {
            this.calculateBindMatrices(child);
        }
    }

What does it look like when you print the matrices for each bone after recursively calling calculateBindMatricies()? Are they all correct before passing to JBullet?

p.s. I only mentioned NiF because your body part names are exactly the same as Morrowind bones :slight_smile:

ziozio,

I actually realised my mistake just now. I was calculating the AABB’s bounds incorrectly… It’s one of those ‘duh!’ moments.

Sorry for the trouble! :slight_smile: