Page 1 of 1

Fully generic example of adding a constraint

Posted: Sat Mar 09, 2013 3:53 pm
by kijoshua2
Could someone provide a good example of how to add a btGeneric6DofSpringConstraint between two rigid bodies, given those two bodies and two anchor points (in world coordinates)? The constraint demo isn't helpful for this, as it doesn't take into account the orientations of the two bodies and most of the values are just arbitrary constants. I need to be able to add a constraint while in-game not knowing anything in advance.

I've tried a number of different things, and some have sorta worked. And that's what makes this difficult for me to debug - at a certain point, I can't tell if I'm doing the linking wrong, or if I have the constraint settings wrong in some way (or established in the wrong order), or if I'm encountering a Bullet quirk. So it would really help to just have a good example. Some part of this that I can be sure is correct.

Code: Select all

void link(btRigidBody* A, btRigidBody* B, btVector3 anchorA, btVector3 anchorB)
{
   btGeneric6DofSpringConstraint* constraint;
   // now what?
}
some keywords: frameInA, frameInB, useLinearReferenceFrameA

Re: Fully generic example of adding a constraint

Posted: Wed Mar 13, 2013 2:43 pm
by norbie
First I would try something easier, like a btPoint2PointConstraint (maybe with some CFM, ERP setting to simulate springiness) to see if everything works as expected, and just after it does would I move on to btGeneric6DofConstraint and btGeneric6DofSpringConstraint.
Theoretically speaking all you need to do is converting the anchor points from world space to local space. I would try something like this:

Code: Select all

void GenericJointDemo::link( btRigidBody* bodyA, btRigidBody* bodyB, const btVector3& anchorA, const btVector3& anchorB )
{
	btTransform localA;
	btTransform localB;

	localA.setIdentity();
	localB.setIdentity();

	// Setting world space origin
	localA.setOrigin( anchorA );
	localB.setOrigin( anchorB );
	// Calculating local space origin
	localA = bodyA->getCenterOfMassTransform().inverse() * localA;
	localB = bodyB->getCenterOfMassTransform().inverse() * localB;
	// Creating constraint
	btGeneric6DofConstraint* constraint = new btGeneric6DofConstraint( *bodyA, *bodyB, localA, localB, true );
	// Rotation is free
	constraint->setAngularLowerLimit( btVector3( 1, 1, 1 ) );
	constraint->setAngularUpperLimit( btVector3( -1, -1, -1 ) );
	// Adding constraint
	m_dynamicsWorld->addConstraint( constraint );

	bodyA->activate( true );
	bodyB->activate( true );
}
I have tried it in GenericJointDemo, but it does not really matter, the only thing you need is a btDynamicsWorld.

Hope this helps.

Re: Fully generic example of adding a constraint

Posted: Wed Mar 13, 2013 4:42 pm
by kijoshua2
Excellent, thank you for that. It all matches what I eventually settled on before posting, except for the "useLinearReferenceFrameA" which I had set to false (doesn't appear to matter?). I never would have trusted it until you confirmed it for me with that example.

There are a bunch of similar posts out there, but all end in either very specific solutions, no solutions, or even wrong conclusions. I hope others will find this as helpful as I did.