Receiving global location of constrained objects

Post Reply
rutracker
Posts: 2
Joined: Thu Dec 30, 2021 9:19 am

Receiving global location of constrained objects

Post by rutracker »

Hi,
As part of my code, I use Bullet to simulate constraints between mesh objects using btConvexHullShape.
I am passing my mesh objects from my code to the world setup and am generating them inside Bullet.
I have gotten to the point where the simulation runs smoothly, and I want to transfer the new location of the mesh objects into my main code, and I am running into trouble.
After some experimenting, it seems that when I run the following reduced code the translation works:

Code: Select all

void WorldSetup::stepSimulation(float deltaTime) {
		btTransform local_position;
		local_position.setIdentity();
		m_dynamicsWorld->getNonStaticRigidBodies().at(0)->setWorldTransform(local_position);
		m_dynamicsWorld->getNonStaticRigidBodies().at(1)->setWorldTransform(local_position);
	
		auto obj1_transform = m_dynamicsWorld->getNonStaticRigidBodies().at(0)->getCenterOfMassTransform().inverse();
		auto obj2_transform = m_dynamicsWorld->getNonStaticRigidBodies().at(1)->getCenterOfMassTransform().inverse();
		translation_data.push_back(obj1_transform);
		translation_data.push_back(obj2_transform);
		//Now the translation_data vecotr is sent to my main code where I apply the translation and rotation to their old position.
}
The problem occurs when I run my simulation with constraints. I set up the world in the following way:

Code: Select all

void WorldSetup::initPhysics()
{
	//code initializing the ground, solver, and more in the code above that I did not mention...
	
	//creating a static object
	btCollisionShape* shape;
	btDefaultMotionState* motionState;
	btTransform bodyTransform;
	btScalar mass;
	
	mass = 0.0;
	shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
	btVector3 localInertia = btVector3(0, 0, 0);
	bodyTransform.setIdentity();
	motionState = new btDefaultMotionState(bodyTransform);
	btRigidBody* staticBody = new btRigidBody(mass, motionState, shape, localInertia);


	float pos1[4]{ 100,100, 100, 0 };
	float color1[4]{ 0.2666, 0.2745, 0.29019, 1 };

	float pos2[4]{ 100, 100, 100, 0 };
	float color2[4]{ 0.2, 0.141, 0.078, 1 };
	
	//loading the mesh objects
	m_data->m_TranslateSpringBodies.push_back(loadMyMesh(m_vertices_list[0], m_faces_list[0], pos1, color1, 50.0f));
	m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBodies.at(0));

	m_data->m_TranslateSpringBodies.push_back(loadMyMesh(m_vertices_list[1], m_faces_list[1], pos2, color2, 50.0f));
	m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBodies.at(1));
	
	//adding a single constraint to force object 0 to stay in a single spot (with the static object)
	btTransform localA;
	btTransform localB;
	localA.setIdentity();
	localB.setIdentity();
	btGeneric6DofSpring2Constraint* constraint = new btGeneric6DofSpring2Constraint(*staticBody, *m_data->m_TranslateSpringBodies.at(0), localA, localB EXTRAPARAMS);

	constraint->setLimit(3, 0, 0);
	constraint->setLimit(4, 0, 0);
	constraint->setLimit(5, 0, 0);

	constraint->enableSpring(0, true);
	constraint->enableSpring(1, true);
	constraint->enableSpring(2, true);


	constraint->setStiffness(0, 50);
	constraint->setStiffness(1, 50);
	constraint->setStiffness(2, 50);

	constraint->setDamping(0, 0.5);
	constraint->setDamping(1, 0.5);
	constraint->setDamping(2, 0.5);

	constraint->setDbgDrawSize(btScalar(5.f));
	m_dynamicsWorld->addConstraint(constraint, true);
	
	//adding a spring constraint between object 0 and object 1
	localA.setIdentity();
	localA.setOrigin(btVector3(-0.2, 5, 8));
	localB.setIdentity();
	localB.setOrigin(btVector3(-3, 3, 14));
	btGeneric6DofSpring2Constraint* constraint2 = new btGeneric6DofSpring2Constraint(*m_data->m_TranslateSpringBodies.at(index_a), *m_data->m_TranslateSpringBodies.at(index_b), localA, localB EXTRAPARAMS);

	constraint2 ->enableSpring(0, true);
	constraint2 ->enableSpring(1, true);
	constraint2 ->enableSpring(2, true);
	constraint2 ->enableSpring(3, true);
	constraint2 ->enableSpring(4, true);
	constraint2 ->enableSpring(5, true);

	constraint2 ->setStiffness(0, 50);
	constraint2 ->setStiffness(1, 50);
	constraint2 ->setStiffness(2, 50);
	constraint2 ->setStiffness(3, 50);
	constraint2 ->setStiffness(4, 50);
	constraint2 ->setStiffness(5, 50);

	constraint2 ->setDamping(0, 0.5);
	constraint2 ->setDamping(1, 0.5);
	constraint2 ->setDamping(2, 0.5);
	constraint2 ->setDamping(3, 0.5);
	constraint2 ->setDamping(4, 0.5);
	constraint2 ->setDamping(5, 0.5);

	m_dynamicsWorld->addConstraint(constraint2 , true);
	constraint2 ->setDbgDrawSize(btScalar(5.f));
}
Now I try to do get the location the same as with the code at the beginning:

Code: Select all

void WorldSetup::stepSimulation(float deltaTime) {
		auto obj1_transform = m_dynamicsWorld->getNonStaticRigidBodies().at(0)->getCenterOfMassTransform().inverse();
		auto obj2_transform = m_dynamicsWorld->getNonStaticRigidBodies().at(1)->getCenterOfMassTransform().inverse();
		translation_data.push_back(obj1_transform);
		translation_data.push_back(obj2_transform);
		//Now, the translation_data vector is sent to my main code, where I apply the translation and rotation to their old position.
}
Doing the following gives me wildly different results, even if the two objects are close to each other in the simulations. In my main code, they are translated to completely different places. The rotation seems to be correct most of the time.

I have been sitting on it for a few days and have no clue where to continue from here. I think it has something to do with local vs. world coordinates, but I don't know what.

Any help will be greatly appreciated.
Thank you! :D
rutracker
Posts: 2
Joined: Thu Dec 30, 2021 9:19 am

Re: Receiving global location of constrained objects

Post by rutracker »

Resolved!
The problem was with applying the transformation in my code.
The transformations I received from bullet were correct, but I made an error when applying them.
Post Reply