getWorldTransform() values don't seem to match drawn output

Post Reply
cout
Posts: 3
Joined: Wed Jul 06, 2016 10:00 am

getWorldTransform() values don't seem to match drawn output

Post by cout »

Hello,
Im trying to implement bulletphysics into a project Im working on currently, and I ran into a couple of problems along the way.
First the setup:
I get a scene serialized as a std::map of the objects, and their properties/parameters (unique ID, vertices, mass, etc). At the moment the transformation data (trans/rot/scale) is baked into the vertices. The plan is to set up a program that deserializes the objects, runs a stepsimulation and sends the updated transformation matrices to a server via TCP to update the actual scene (rather convoluted, I know).

Now my first attempt was to write my own solution, taking the "Hello World"-example from the wiki as a base, just adding in my Objects as btConvexHulls and send back the data from

Code: Select all

btTransform transMtx;
body->getMotionState()->getWorldTransform(transMtx);
transMtx.getOrigin()
...the results are....interesting.
The scene consists of a table (static, 4 cubes for legs,1 for the tabletop), flat cube for the ground(static) and 3 primitive objects(dynamic) above the table.
The objects don't collide at all, and seem to jump arround and odd angles, and somehow seem to act like some sort of pendulum, swinging back and forth suspended in midair.

To get a better grasp on what was going on, I decided to throw everything into the basicexample.cpp of the example browser(I literally ctrl+c/ctrl+v'ed it), and, lo and behold, the scene rendered by the debugdrawer actually matches the original one. The objects fall down, collide with the table and each other, and finally hit the ground.
But...the transformation matrices I get from the m_dynamicsWorld and/or motionState() aren't representing that behaviour at all. The values I send back just describe the 3 dynamic objects falling down, no collision with each other, or the table. They all come to rest slightly below the ground block, clipped into each other, but on the same height.

Sooo...
1. Where would I be able to read out the correct values for the transformation matrices, including the collisions ? I tried several functions, but the results were all the same.
2. While the scene, objects and collisions are all there in the debugdrawer-representation, they behave a bit odd. Could it be that the center of mass of all the dynamic objects isn't actually in the center of their collisionshapes, since they were build from the vertices in their "final" position instead of being build with (0,0,0) as the center ?

Thanks,
cout

If it helps any, here's the changes to the basicexample.cpp:

Code: Select all

void BasicExample::initPhysics()
{
	
     std::vector<SceneObject> retval;

       //deserialization happens here
	
	std::vector<int> extract_Objects(std::map<int, SceneObjects> const& Object);
	{
		for (auto const& element : Object)
		{
			retval.push_back(element.second);
		}


	}

	m_guiHelper->setUpAxis(2);

	createEmptyDynamicsWorld();
	
	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);

	if (m_dynamicsWorld->getDebugDrawer())
		m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);

	m_dynamicsWorld->setGravity(btVector3(0, 0, -9.81));

 for (unsigned int i = 0; i < physObject.size(); i++)
	{

		std::vector<std::vector<float>> vertices = retval[i].vertices;
		btConvexHullShape *convex = new btConvexHullShape();
		for (unsigned int j = 0; j < vertices.size(); j++)
		{
			convex->addPoint(btVector3(vertices.at(j)[0], vertices.at(j)[1], vertices.at(j)[2]));
		}

		btTransform tr;
		tr.setIdentity();
		btScalar mass(retval[i].mass);
		btVector3 localInertia(1, 1, 1);
		if (mass != 0.f)
		{
			convex->calculateLocalInertia(mass, localInertia);
		}
		createRigidBody(mass, tr, convex);

	}
        m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void BasicExample::renderScene()
{
	CommonRigidBodyBase::renderScene();
	//one of the spots I tried to grab the transformed values to transfere from
}
 
Last edited by cout on Sat Jul 09, 2016 6:37 pm, edited 1 time in total.
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: getWorldTransform() values don't seem to match drawn out

Post by hyyou »

Code: Select all

bulletRigidBody->getCenterOfMassPosition()
bulletRigidBody->getOrientation();
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: getWorldTransform() values don't seem to match drawn out

Post by benelot »

Using the methods hyou proposed should actually give you the exact positions and orientations. The center of mass position is at the center of mass of the collision shape. You can also directly get the data from the world transform by getOrigin and getOrientation. The motionstate might include some interpolation, it is mainly meant for rendering purposes but they should basically represent the same behavior. btRigidBody1->getWorldTransform() is the exact one.
cout
Posts: 3
Joined: Wed Jul 06, 2016 10:00 am

Re: getWorldTransform() values don't seem to match drawn out

Post by cout »

The methods actually didn't help at all.
Setting the center of mass seems to also set the origin, and vice versa...and getOrientation() returns a quaternion, which won't do anything for the wrong translation values.
There is also a setCenterOfMassOffset()...which doesn't seem to to anything, at all.

I sort of "solved" my second question, however:
As I wrote in my first post, the vertice data I get has the transformations already baked in, e.g. a cube with sidelengths of 10 at point (10,10,10) will be send over just as (5,5,5)......(15,15,15), instead of (-5,-5,-5).......(5,5,5) and a translation to (10,10,10).

And my hunch about the center of mass/origin being wrong seems to be correct:
When you build btConvexHullShapes like that, the object will look like it has been created correctly, the cube will show up with (10,10,10) as it's center in the debugdrawer, and the visible shape will collide as expected.
However: The origin (and the center of mass) of the object will still be taken as (0,0,0), meaning after hitting something while falling down, it will look like the object attempts to fall towards the scene's origin.
It basically reacts like an invisible "ghost" rod with the cube attatched to one end, but all the weight of it concentrated on the other.

What I did now was to calculate the center of the vertices data per object I get, substract the center from all the vertices, create the btConvexHullShape with those values, and btTransform.setOrigin(center) it. This is anything but clean, but at least the simulation now works as expected.

I still have some odd issues with the data I send out (question 1). Grabbing the Origin from the worldtransfom results in some strange values on the backend, the positions of the dynamic objects are off by factors of up to 2, but not consistently. Static Objects work correctly (in the debugdrawer everything works).
Since I implemented it into the basicexample.cpp of the example browser, knowing where in the code/file I can savely grab the correct transformed values would really help me finding the actual error.
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: getWorldTransform() values don't seem to match drawn out

Post by benelot »

I have never heard of the issues you are experiencing. Since you already implement things in the example browser, could you make a simple example that shows your issue?
cout
Posts: 3
Joined: Wed Jul 06, 2016 10:00 am

Re: getWorldTransform() values don't seem to match drawn out

Post by cout »

I did some more tests, and can now confirm that the problem of question 1 isn't on the bulletphysics side. The values that get send over are in fact correct, but the backend does some weird things with it I don't really have figured out yet (sometimes it does replace the old transformation matrix with the new one, sometimes it does multiplay with it, for example).
Since this isn't a bulletphysics problem, I guess it can be marked as solved.
Post Reply