Articulated body resting on a plane starts to jump

Herleson
Posts: 9
Joined: Wed Mar 28, 2012 10:55 pm

Articulated body resting on a plane starts to jump

Post by Herleson »

Hello,

(Sorry if this is a newbie question)

I´m creating an articulated object using Bullet. The main part of the code is below:

Code: Select all

btScalar alturaCorpo = 77.5;

void GeraObjetoBullet()
{
	btTransform transOrigem;
	btVector3 inerciaPadrao(0,0,0);
	btScalar massaCorpo;

	fPlano = new btStaticPlaneShape(btVector3(0,1,0), 0);
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(0, 0, 0));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	cPlano = new btRigidBody(0, motionStatePadrao, fPlano, inerciaPadrao);

	fPelvis = new btCompoundShape;
	btCollisionShape* parte1 = new btCapsuleShape(btScalar(2.5), btScalar(10));
	btCollisionShape* parte2 = new btCapsuleShape(btScalar(2.5), btScalar(30));
	transOrigem.setIdentity();
	fPelvis -> addChildShape(transOrigem, parte1);
	transOrigem.setOrigin(btVector3(0, -5, 0));
	transOrigem.setRotation(btQuaternion(btVector3(0, 0, 1), pi/2));
	fPelvis -> addChildShape(transOrigem, parte2);
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(0, alturaCorpo, 0));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fPelvis -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cPelvis = new btRigidBody(massaCorpo, motionStatePadrao, fPelvis, inerciaPadrao);
	
	fTronco = new btCompoundShape;
	parte1 = new btCapsuleShape(btScalar(2.5), btScalar(30));
	parte2 = new btCapsuleShape(btScalar(2.5), btScalar(50));
	transOrigem.setIdentity();
	fTronco -> addChildShape(transOrigem, parte1);
	transOrigem.setOrigin(btVector3(0, 15, 0));
	transOrigem.setRotation(btQuaternion(btVector3(0, 0, 1), pi/2));
	fTronco -> addChildShape(transOrigem, parte2);
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(0), btScalar(alturaCorpo + 20), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fTronco -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cTronco = new btRigidBody(massaCorpo, motionStatePadrao, fTronco, inerciaPadrao);

	fCabeca = new btCompoundShape;
	parte1 = new btCapsuleShape(btScalar(2.5), btScalar(15));
	parte2 = new btSphereShape(btScalar(10));
	transOrigem.setIdentity();
	fCabeca -> addChildShape(transOrigem, parte1);
	transOrigem.setOrigin(btVector3(0, btScalar(7.5), 0));
	fCabeca -> addChildShape(transOrigem, parte2);
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(0), btScalar(alturaCorpo + 44.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fCabeca -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cCabeca = new btRigidBody(massaCorpo, motionStatePadrao, fCabeca, inerciaPadrao);

	fCoxaEsq = new btCapsuleShape(btScalar(2.5), btScalar(30));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(15), btScalar(alturaCorpo - 20), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fCoxaEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cCoxaEsq = new btRigidBody(massaCorpo, motionStatePadrao, fCoxaEsq, inerciaPadrao);
	
	fCoxaDir = new btCapsuleShape(btScalar(2.5), btScalar(30));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-15), btScalar(alturaCorpo - 20), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fCoxaDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cCoxaDir = new btRigidBody(massaCorpo, motionStatePadrao, fCoxaDir, inerciaPadrao);

	fCanelaEsq = new btCapsuleShape(btScalar(2.5), btScalar(40));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(15), btScalar(alturaCorpo - 55), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fCanelaEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cCanelaEsq = new btRigidBody(massaCorpo, motionStatePadrao, fCanelaEsq, inerciaPadrao);

	fCanelaDir = new btCapsuleShape(btScalar(2.5), btScalar(40));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-15), btScalar(alturaCorpo - 55), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fCanelaDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cCanelaDir = new btRigidBody(massaCorpo, motionStatePadrao, fCanelaDir, inerciaPadrao);

	fPeEsq = new btBoxShape(btVector3(btScalar(3.5), btScalar(2.5), btScalar(5)));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(15), btScalar(alturaCorpo - 72.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fPeEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cPeEsq = new btRigidBody(massaCorpo, motionStatePadrao, fPeEsq, inerciaPadrao);

	fPeDir = new btBoxShape(btVector3(btScalar(3.5), btScalar(2.5), btScalar(5)));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-15), btScalar(alturaCorpo - 72.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fPeDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cPeDir = new btRigidBody(massaCorpo, motionStatePadrao, fPeDir, inerciaPadrao);

	fAntebracoEsq = new btCapsuleShape(btScalar(2.5), btScalar(20));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(25), btScalar(alturaCorpo + 25), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fAntebracoEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cAntebracoEsq = new btRigidBody(massaCorpo, motionStatePadrao, fAntebracoEsq, inerciaPadrao);
	
	fAntebracoDir = new btCapsuleShape(btScalar(2.5), btScalar(20));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-25), btScalar(alturaCorpo + 25), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fAntebracoDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cAntebracoDir = new btRigidBody(massaCorpo, motionStatePadrao, fAntebracoDir, inerciaPadrao);

	fBracoEsq = new btCapsuleShape(btScalar(2.5), btScalar(25));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(25), btScalar(alturaCorpo + 2.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fBracoEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cBracoEsq = new btRigidBody(massaCorpo, motionStatePadrao, fBracoEsq, inerciaPadrao);

	fBracoDir = new btCapsuleShape(btScalar(2.5), btScalar(25));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-25), btScalar(alturaCorpo + 2.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fBracoDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cBracoDir = new btRigidBody(massaCorpo, motionStatePadrao, fBracoDir, inerciaPadrao);

	fMaoEsq = new btBoxShape(btVector3(btScalar(2.5), btScalar(3.5), btScalar(2.5)));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(25), btScalar(alturaCorpo - 13.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fMaoEsq -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cMaoEsq = new btRigidBody(massaCorpo, motionStatePadrao, fMaoEsq, inerciaPadrao);

	fMaoDir = new btBoxShape(btVector3(btScalar(2.5), btScalar(3.5), btScalar(2.5)));
	transOrigem.setIdentity();
	transOrigem.setOrigin(btVector3(btScalar(-25), btScalar(alturaCorpo - 13.5), btScalar(0)));
	motionStatePadrao = new btDefaultMotionState(transOrigem);
	massaCorpo = btScalar(1);
	fMaoDir -> calculateLocalInertia(massaCorpo, inerciaPadrao);
	cMaoDir = new btRigidBody(massaCorpo, motionStatePadrao, fMaoDir, inerciaPadrao);

	mundoDinamico -> addRigidBody(cPlano);
	mundoDinamico -> addRigidBody(cPelvis);
	mundoDinamico -> addRigidBody(cTronco);
	mundoDinamico -> addRigidBody(cCabeca);
	mundoDinamico -> addRigidBody(cCoxaEsq);
	mundoDinamico -> addRigidBody(cCoxaDir);
	mundoDinamico -> addRigidBody(cCanelaEsq);
	mundoDinamico -> addRigidBody(cCanelaDir);
	mundoDinamico -> addRigidBody(cPeEsq);
	mundoDinamico -> addRigidBody(cPeDir);
	mundoDinamico -> addRigidBody(cAntebracoEsq);
	mundoDinamico -> addRigidBody(cAntebracoDir);
	mundoDinamico -> addRigidBody(cBracoEsq);
	mundoDinamico -> addRigidBody(cBracoDir);
	mundoDinamico -> addRigidBody(cMaoEsq);
	mundoDinamico -> addRigidBody(cMaoDir);


	btTransform transArtA, transArtB;
	
	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(5),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(-15), btScalar(0)));
	btGeneric6DofConstraint* artPelvisTronco = new btGeneric6DofConstraint(*cPelvis, *cTronco, transArtA, transArtB, false);
	artPelvisTronco -> setAngularLowerLimit(btVector3(-pi/2, 0, 0));
	artPelvisTronco -> setAngularUpperLimit(btVector3(pi/4, 0, 0));
	mundoDinamico -> addConstraint(artPelvisTronco, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(15),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(-7.5), btScalar(0)));
	btGeneric6DofConstraint* artTroncoCabeca = new btGeneric6DofConstraint(*cTronco, *cCabeca, transArtA, transArtB, false);
	artTroncoCabeca -> setAngularLowerLimit(btVector3(-pi/2, 0, -pi/4));
	artTroncoCabeca -> setAngularUpperLimit(btVector3(pi/2, 0, pi/4));
	mundoDinamico -> addConstraint(artTroncoCabeca, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(15),btScalar(-5),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(15), btScalar(0)));
	btGeneric6DofConstraint* artPelvisCoxaEsq = new btGeneric6DofConstraint(*cPelvis, *cCoxaEsq, transArtA, transArtB, false);
	artPelvisCoxaEsq -> setAngularLowerLimit(btVector3(-pi/2, 0, -pi/2));
	artPelvisCoxaEsq -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artPelvisCoxaEsq, true);
	
	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(-15),btScalar(-5),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(15), btScalar(0)));
	btGeneric6DofConstraint* artPelvisCoxaDir = new btGeneric6DofConstraint(*cPelvis, *cCoxaDir, transArtA, transArtB, false);
	artPelvisCoxaDir -> setAngularLowerLimit(btVector3(-pi/2, 0, -pi/2));
	artPelvisCoxaDir -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artPelvisCoxaDir, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-15),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(20), btScalar(0)));
	btGeneric6DofConstraint* artCoxaEsqCanelaEsq = new btGeneric6DofConstraint(*cCoxaEsq, *cCanelaEsq, transArtA, transArtB, false);
	artCoxaEsqCanelaEsq -> setAngularLowerLimit(btVector3(-pi/2, 0, 0));
	artCoxaEsqCanelaEsq -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artCoxaEsqCanelaEsq, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-15),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(20), btScalar(0)));
	btGeneric6DofConstraint* artCoxaDirCanelaDir = new btGeneric6DofConstraint(*cCoxaDir, *cCanelaDir, transArtA, transArtB, false);
	artCoxaDirCanelaDir -> setAngularLowerLimit(btVector3(-pi/2, 0, 0));
	artCoxaDirCanelaDir -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artCoxaDirCanelaDir, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-20),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(0), btScalar(0)));
	btGeneric6DofConstraint* artCanelaEsqPeEsq = new btGeneric6DofConstraint(*cCanelaEsq, *cPeEsq, transArtA, transArtB, false);
	artCanelaEsqPeEsq -> setAngularLowerLimit(btVector3(-pi/4, -pi/4, 0));
	artCanelaEsqPeEsq -> setAngularUpperLimit(btVector3(pi/4, pi/4, 0));
	mundoDinamico -> addConstraint(artCanelaEsqPeEsq, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-20),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(0), btScalar(0)));
	btGeneric6DofConstraint* artCanelaDirPeDir = new btGeneric6DofConstraint(*cCanelaDir, *cPeDir, transArtA, transArtB, false);
	artCanelaDirPeDir -> setAngularLowerLimit(btVector3(-pi/4, -pi/4, 0));
	artCanelaDirPeDir -> setAngularUpperLimit(btVector3(pi/4, pi/4, 0));
	mundoDinamico -> addConstraint(artCanelaDirPeDir, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(25),btScalar(15),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(10), btScalar(0)));
	btGeneric6DofConstraint* artTroncoAntebracoEsq = new btGeneric6DofConstraint(*cTronco, *cAntebracoEsq, transArtA, transArtB, false);
	artTroncoAntebracoEsq -> setAngularLowerLimit(btVector3(-pi/4, 0, -pi/4));
	artTroncoAntebracoEsq -> setAngularUpperLimit(btVector3(pi/4, 0, pi/4));
	mundoDinamico -> addConstraint(artTroncoAntebracoEsq, true);
	
	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(-25),btScalar(15),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(10), btScalar(0)));
	btGeneric6DofConstraint* artTroncoAntebracoDir = new btGeneric6DofConstraint(*cTronco, *cAntebracoDir, transArtA, transArtB, false);
	artTroncoAntebracoDir -> setAngularLowerLimit(btVector3(-pi/4, 0, -pi/4));
	artTroncoAntebracoDir -> setAngularUpperLimit(btVector3(pi/4, 0, pi/4));
	mundoDinamico -> addConstraint(artTroncoAntebracoDir, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-10),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(12.5), btScalar(0)));
	btGeneric6DofConstraint* artAntebracoEsqBracoEsq = new btGeneric6DofConstraint(*cAntebracoEsq, *cBracoEsq, transArtA, transArtB, false);
	artAntebracoEsqBracoEsq -> setAngularLowerLimit(btVector3(-pi/2, 0, 0));
	artAntebracoEsqBracoEsq -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artAntebracoEsqBracoEsq, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-10),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(12.5), btScalar(0)));
	btGeneric6DofConstraint* artAntebracoDirBracoDir = new btGeneric6DofConstraint(*cAntebracoDir, *cBracoDir, transArtA, transArtB, false);
	artAntebracoDirBracoDir -> setAngularLowerLimit(btVector3(-pi/2, 0, 0));
	artAntebracoDirBracoDir -> setAngularUpperLimit(btVector3(pi/2, 0, 0));
	mundoDinamico -> addConstraint(artAntebracoDirBracoDir, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-12.5),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(0), btScalar(0)));
	btGeneric6DofConstraint* artBracoEsqMaoEsq = new btGeneric6DofConstraint(*cBracoEsq, *cMaoEsq, transArtA, transArtB, false);
	artBracoEsqMaoEsq -> setAngularLowerLimit(btVector3(-pi/4, -pi/4, 0));
	artBracoEsqMaoEsq -> setAngularUpperLimit(btVector3(pi/4, pi/4, 0));
	mundoDinamico -> addConstraint(artBracoEsqMaoEsq, true);

	transArtA = btTransform::getIdentity();
	transArtB = btTransform::getIdentity();
	transArtA.setOrigin(btVector3(btScalar(0),btScalar(-12.5),btScalar(0)));
	transArtB.setOrigin(btVector3(btScalar(0),btScalar(0), btScalar(0)));
	btGeneric6DofConstraint* artBracoDirMaoDir = new btGeneric6DofConstraint(*cBracoDir, *cMaoDir, transArtA, transArtB, false);
	artBracoDirMaoDir -> setAngularLowerLimit(btVector3(-pi/4, -pi/4, 0));
	artBracoDirMaoDir -> setAngularUpperLimit(btVector3(pi/4, pi/4, 0));
	mundoDinamico -> addConstraint(artBracoDirMaoDir, true);
}
The alturaCorpo variable is at the center of the Pelvis, and it´s the referential for the rest of the body. The distance between this center and the floor is exactly 75. However, when I define a value of 75 to this variable, the object starts the simulation jumping. Only using the value of 77.5 this problem is solved, however the body does a little fall.

Even when using a simple cube on the floor, the same behavior happens.

I know that the collision engine is responsible for that, But I think it should exists a way to tell Bullet that a Dynamic Body is resting on the floor at the beggining of the simulation. Or am I doing something wrong?

Thanks for the attention.
CookieMonster
Posts: 49
Joined: Sun Jan 29, 2012 10:01 pm

Re: Articulated body resting on a plane starts to jump

Post by CookieMonster »

You must add any treshold for triangle shapes to the distance from the ground and tell the body to be island sleeping.
Herleson
Posts: 9
Joined: Wed Mar 28, 2012 10:55 pm

Re: Articulated body resting on a plane starts to jump

Post by Herleson »

Thanks for the reply, CookieMoster!

However, what type of threshold should be implemented? And on which rigid body?

Also, I found no material about Island Management in Bullet. Do you have any link so I can learn more?

Thanks in advance!