chandlerprall / Physijs

Physics plugin for Three.js
MIT License
2.77k stars 455 forks source link

Why are my ConeTwist constraints so bouncy? #166

Open josephrocca opened 10 years ago

josephrocca commented 10 years ago

Here's some basic code I'm using to create my constraint. Note that I'm setting the rotational limit to 0,0,0 since I want the joints to be rigid for now:

    // Add constraints
    var constraint = new Physijs.ConeTwistConstraint(
        bone, // First object to be constrained
        node, // Second object to be constrained
        nodePosition // point in the scene to apply the constraint
    );
   scene.addConstraint( constraint );
   constraint.setLimit( 0 , 0 , 0 ); // rotational limit, in radians, for each axis

Using the above code, I create a little 'quadraped' thingy with nodes and bones, but things don't quite go as planned:

image

As you can see, the constraint can barely hold any weight at all. I expected them to be completely rigid by default, or for there to be restitution settings for the joint.

Is this normal behaviour? Am I doing something wrong? How can a rigid joint be achieved?

Thanks!

P.S A possible hacky solution: constraint.setMotorTarget() to hold the bones rigidly?? Surely rigid constraints is a fairly common need though?

EDIT: Here's the ConeTwist function from bullet - it seems to have the arguments that I need (softness/relaxation):

void btConeTwistConstraint::setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan,btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
josephrocca commented 10 years ago

Even if someone could just say "you're doing something wrong, it is possible to make rigid constraints" that would be a real help.

chandlerprall commented 10 years ago

Sorry, been rather busy lately; I'll take a look at this tonight

josephrocca commented 10 years ago

Thanks a heap. Btw, I've uploaded my program here: josephrocca.com/creature if that helps. You can click and drag on the node to create bones and press 'P' to unpause

chandlerprall commented 10 years ago

After playing with the ConeTwist constraint and looking into Bullet's implementation I don't think you're going to get what you want with that constraint. You probably want to just use a DOFConstraint where no linear movement and very little angular movement is allowed.

josephrocca commented 10 years ago

I've just tried this and am getting the same result. The linear part is working fine, but the angular part acts as if it's very springy and weak. The new constraints are on line 322 of Engine.js if you wanted to put a breakpoint in, and here it is for convenience:

var constraint1 = new Physijs.DOFConstraint(
    bone, // First object to be constrained
    b.node1.getMesh(), // Second object to be constrained
    b.node1.getMesh().position // point in the scene to apply the constraint
);
var constraint2 = new Physijs.DOFConstraint(
    bone, // First object to be constrained
    b.node2.getMesh(), // Second object to be constrained
    b.node2.getMesh().position // point in the scene to apply the constraint
);
this.scene.addConstraint( constraint1 );
this.scene.addConstraint( constraint2 );
constraint1.setLinearLowerLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint1.setLinearUpperLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint1.setAngularLowerLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint1.setAngularUpperLimit( new THREE.Vector3( 0.01, 0.01, 0.01 ) );
constraint2.setLinearLowerLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint2.setLinearUpperLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint2.setAngularLowerLimit( new THREE.Vector3( 0, 0, 0 ) );
constraint2.setAngularUpperLimit( new THREE.Vector3( 0.01, 0.01, 0.01 ) );

I just read this on bullet wiki:

Keep masses for dynamic objects similar: If an object of 100 kg rests on an object of 0.1 kg, the simulation will have difficulties. In order to avoid large mass ratios, keep mass of objects similar (in the order of a few kg)

This doesn't apply though does it? That is, since I've set the plane's mass to 0 and so it's not dynamic. The node mass is ~4 and the bones are ~17.

EDIT: I suppose this is as you expected, but if I lower the gravity from 100 to 50, the constraints hold up a little better, but are still very springy.

EDIT: I also read on this wiki page that it's recommended to keep gravity set at about 10. The constraints hold up fine for this, but everything falls very slowly and it's all very moon-like.

josephrocca commented 10 years ago

... should I wait for goblin physics? (I tweeted to you)

josephrocca commented 10 years ago

From this thread: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=3910

The iterative constrains solver constraints might be too weak indeed, especially when 'large' mass ratios are involved (even 1:10 can be problematic). Increasing the number of iterations, or decreasing the internal timestep might improve things. Have you tried btSliderConstraint and/or btGeneric6DofConstraint? They might converge better.

chandlerprall commented 10 years ago

That's an interesting find. How do the constraints hold up if you make the masses closer in value?