Ragdoll&floor problem (falling through)

Yes, it’s again about ragdolls :stuck_out_tongue:

I have created a ragdoll class and it makes nearly the same ragdoll as the one from the tutorials. (it’s the first step to my uber-awesome stickieman ragdoll)

and to my suprise, it actually works : I can let him bounce through the map, throw him at buildings, crush him under big physics speres,…

But when I let him fall from a distance onto the ground (also a physics node) it gets stuck with both it’s legs in the map.

how can I fix this?

Use ccd, continuous collision detection, see the TestCcd test and javadoc.

1 Like

well, it works in the sense that now only its feet get stuck :slight_smile:



but making the value smaller only affects my fps, not if it gets stuck or not



node.setCcdMotionThreshold(0.00001f);

has the same effect as

node.setCcdMotionThreshold(1f);

(feet gets stuck)

When the feet get stuck, you sure that you applied ccd to the feet? Re-read the ccd javadoc, a motion threshold of 0.000001f probably makes no sense, just as the 1f doesnt. It should be about a half of the “thinnest” 3d object you expect to be penetrated.

actually, it’s not a real feet: it’s his lower legg.

I create that limb with this method:

[java] private PhysicsNode createLimb(float width, float height, Vector3f location, boolean rotate) {

int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y;



Geometry limb = new Geometry(“limb”, new Box(width, height, width));

limb.setMaterial(mat);



CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis);

PhysicsNode node = new PhysicsNode(limb, shape);

node.setLocalTranslation(location);

node.setCcdMotionThreshold(height / 2);



return node;

}[/java]

and those limbs are boxes because I don’t know how to make filled cilinders.

Cylinders are always filled in the physics, dont let the debug shape distract you.

yeah, but when you see the cylinders (replace box by cilinder) you can see through them, thats what I mean.

do you have any idea why the ccd doesn’t work?

Check if your geometry is really formed like the collision shape by adding [java]node.attachDebugShape(assetManager);[/java] in line 11

yes, it looks like that.

Here is the complete code, I think it"ll be easier for you to see whats happening

[java]



/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package org.mvd.jme3.models.ragdoll;



    import com.jme3.asset.AssetManager;

    import com.jme3.bullet.PhysicsSpace;

    import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

    import com.jme3.bullet.joints.PhysicsConeJoint;

    import com.jme3.bullet.joints.PhysicsJoint;

    import com.jme3.bullet.nodes.PhysicsNode;

    import com.jme3.material.Material;

    import com.jme3.math.Vector3f;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.Node;

    import com.jme3.scene.shape.Box;



    /**

    *
  • @author maarten

    */

    public class simpleRagdoll extends Node {



    private Material mat;



    private PhysicsNode shoulders;

    private PhysicsNode uArmL;

    private PhysicsNode uArmR;

    private PhysicsNode lArmL;

    private PhysicsNode lArmR;

    private PhysicsNode body;

    private PhysicsNode hips;

    private PhysicsNode uLegL;

    private PhysicsNode uLegR;

    private PhysicsNode lLegR;

    private PhysicsNode lLegL;



    public simpleRagdoll(Material mat) {

    this.mat = mat;



    createRagDoll();

    }



    private void createRagDoll() {

    shoulders = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 1.5f, 0), true);

    uArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, 0.8f, 0), false);

    uArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, 0.8f, 0), false);

    lArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, -0.2f, 0), false);

    lArmR = createLimb(0.2f, 0.5f, new Vector3f(0.75f, -0.2f, 0), false);

    body = createLimb(0.2f, 1.0f, new Vector3f(0.00f, 0.5f, 0), false);

    hips = createLimb(0.2f, 0.5f, new Vector3f(0.00f, -0.5f, 0), true);

    uLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -1.2f, 0), false);

    uLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -1.2f, 0), false);

    lLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f, -2.2f, 0), false);

    lLegR = createLimb(0.2f, 0.5f, new Vector3f(0.25f, -2.2f, 0), false);



    join(body, shoulders, new Vector3f(0f, 1.4f, 0));

    join(body, hips, new Vector3f(0f, -0.5f, 0));



    join(uArmL, shoulders, new Vector3f(-0.75f, 1.4f, 0));

    join(uArmR, shoulders, new Vector3f(0.75f, 1.4f, 0));

    join(uArmL, lArmL, new Vector3f(-0.75f, .4f, 0));

    join(uArmR, lArmR, new Vector3f(0.75f, .4f, 0));



    join(uLegL, hips, new Vector3f(-.25f, -0.5f, 0));

    join(uLegR, hips, new Vector3f(.25f, -0.5f, 0));

    join(uLegL, lLegL, new Vector3f(-.25f, -1.7f, 0));

    join(uLegR, lLegR, new Vector3f(.25f, -1.7f, 0));



    this.attachChild(shoulders);

    this.attachChild(body);

    this.attachChild(hips);

    this.attachChild(uArmL);

    this.attachChild(uArmR);

    this.attachChild(lArmL);

    this.attachChild(lArmR);

    this.attachChild(uLegL);

    this.attachChild(uLegR);

    this.attachChild(lLegL);

    this.attachChild(lLegR);







    }



    private PhysicsNode createLimb(float width, float height, Vector3f location, boolean rotate) {

    int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y;

    Geometry limb;

    if(rotate){

    limb = new Geometry(“limb”, new Box(height, width, width));

    }else{

    limb = new Geometry(“limb”, new Box(width, height, width));

    }



    limb.setMaterial(mat);



    CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis);

    PhysicsNode node = new PhysicsNode(limb, shape);

    node.setLocalTranslation(location);

    node.setCcdMotionThreshold(height / 2);

    node.setMass(2f);

    return node;

    }



    private PhysicsJoint join(PhysicsNode A, PhysicsNode B, Vector3f connectionPoint) {

    Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f());

    Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f());

    PhysicsConeJoint joint = new PhysicsConeJoint(A, B, pivotA, pivotB);

    joint.setLimit(1f, 1f, 0);

    return joint;

    }



    public void shoot() {

    body.applyImpulse(new Vector3f(0f, 50f, 0f), body.getLocalTranslation());

    }

    public void createDebugShape(AssetManager assetManager){

    shoulders.attachDebugShape(assetManager);

    uArmL.attachDebugShape(assetManager);

    uArmR.attachDebugShape(assetManager);

    lArmL.attachDebugShape(assetManager);

    lArmR .attachDebugShape(assetManager);

    body.attachDebugShape(assetManager);

    hips .attachDebugShape(assetManager);

    uLegL .attachDebugShape(assetManager);

    uLegR.attachDebugShape(assetManager);

    lLegL .attachDebugShape(assetManager);

    lLegR.attachDebugShape(assetManager);



    }

    }

    [/java]



    and in my simplegame class I create my landscape with

    [java]

    sceneModel = assetManager.loadModel(“Scenes/town/main.scene”);

    sceneModel.setLocalScale(2f);



    CompoundCollisionShape sceneShape =

    CollisionShapeFactory.createMeshCompoundShape((Node) sceneModel);

    landscape = new PhysicsNode(sceneModel, sceneShape, 0);

    rootNode.attachChild(landscape);



    bulletAppState.getPhysicsSpace().add(landscape);

    [/java]



    and create the ragdoll with

    [java]

    Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);

    mat1.setColor(“m_Color”, ColorRGBA.Blue);



    ragdoll=new simpleRagdoll(mat1);



    ragdoll.setLocalTranslation(new Vector3f(0, 50, 0));

    ragdoll.setLocalRotation(Quaternion.IDENTITY);

    ragdoll.createDebugShape(assetManager);

    bulletAppState.getPhysicsSpace().addAll(ragdoll);

    rootNode.attachChild(ragdoll);

    [/java]





    thank you for the help so far :slight_smile:

    I also have another question: when you ad a physicsNode to a normal node and you call on that node getchildren you get a list of spatials. how do you get the original physicsNode back?

I’ve added another fix but its not the solution:

[java]

if(width> height){

node.setCcdMotionThreshold(height / 2);

}else{

node.setCcdMotionThreshold( width);

}[/java]

the ragdoll keeps getting stuck with his lower legg in the floor

just out of curiousity (and another reason to bump this thread :p)

has anyone been able to reproduce this problem?

It seems like I’m the only person that got that issue.

I’ve searched on another forum and found this: http://forum.unity3d.com/threads/48481-Bullet-Collision-Problem-then-it-flys-fast-(SOLVED)



Not yet tried but just wondering if that could be the problem?

c’mon, is nobody willing/able to help?

who else get’s this problem?

is there a workaround?

is this a bug in jbullet?

is there an error in my code?

If no one’s answering, assume nobody knows, sorry, developers can’t solve 100% of all problems posted here, though they have a very good ratio.

I know, it’s just too bad I need to give up on it

Hi there



I just built your code on my machine as you asked. It produces the same problem here - I would have been surprised if not.



Did you find a solution meanwhile?

What in the world is so important about letting a ragdoll fall from 10000000 meters? With forces this high most physics engines produce errors, I could not reproduce this with the ragdoll test and heights that leave the far plane of the cam… oO I think this is an artificial issue really…

Actually 30 World Units are enough.



I’d say the error occurs because the lower leg, which hits the ground first or is processed first, is absolutely parallel to it. Or both lower legs hit the ground at the exact same moment, what causes some anomaly. These are indeed artificial cases.



If I manipulate the ragdoll only a tiny bit by calling the given shoot method, it turns out just fine.



Edit: Here’s a ZIP of the jMonkey Platform Project which should reproduce the error.

Edit2: Removed the Link because the file was no longer available.

1 Like

Thanks, good to know, also explains why it was not happening in the ragdoll test (which is more like an actual game situation).