Can't get it working

Tunis
Posts: 5
Joined: Wed Jun 02, 2010 8:29 am

Can't get it working

Post by Tunis »

Hello!

This is my first post on this forum but I have been struggling with Bullet a couple of weeks total. I used it about a year ago and I was impressed by it.
So I thought I should give it a try and implement it in my current game.

Now to the problem. It can be some compiler settings that I haven't set correct or it could be my lack of knowledge in Bullet that causes this but sometimes when I compile my very basic program which creates some rigid bodies that either fall to the ground or are hinged together I get a crash in
btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD()

and more specifically on this row:

__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));

It happens as soon as I step the world if I have created a btHeightfieldTerrainShape or I have created too many objects (5 of them)...

I initialise my world like this:

Code: Select all

	mBroadPhase = OGRE_NEW_T(bt32BitAxisSweep3, Ogre::MEMCATEGORY_GENERAL)(worldMin, worldMax);
	// collision configuration and dispatcher
	mCollisionConfiguration = OGRE_NEW_T(btDefaultCollisionConfiguration, Ogre::MEMCATEGORY_GENERAL);
	mCollisionDispatcher = OGRE_NEW_T(btCollisionDispatcher, Ogre::MEMCATEGORY_GENERAL)(mCollisionConfiguration);
	// create the solver
	mSolver = OGRE_NEW_T(btSequentialImpulseConstraintSolver, Ogre::MEMCATEGORY_GENERAL);
	// finally create the world
	mWorld = OGRE_NEW_T(btDiscreteDynamicsWorld, Ogre::MEMCATEGORY_GENERAL)(mCollisionDispatcher, mBroadPhase, mSolver, mCollisionConfiguration);

	mWorld->setGravity(btVector3(0, -9.82, 0));
And I then create some girders like this:

Code: Select all

	Girder *girder = pm->createGirder(Ogre::Vector3(3, 5, 3), Ogre::Vector3(3, 5, 6), 0.3, NULL);
	girder = pm->createGirder(Ogre::Vector3(3, 5, 6), Ogre::Vector3(3, 5, 9), 0.3, girder);
	girder = pm->createGirder(Ogre::Vector3(3, 5, 9), Ogre::Vector3(3, 5, 12), 0.3, girder);
And the Girder Constructor looks like this:

Code: Select all

Girder::Girder(Ogre::Vector3 start, Ogre::Vector3 end, Ogre::Real thickness, Ogre::SceneManager *mgr, Girder *anchor1, Girder *anchor2)
{
	mGirderID = mNextGirderID++;
	mNode = mgr->getRootSceneNode()->createChildSceneNode();

	Ogre::Real length = (end - start).length();
	mCollisionShape = OGRE_NEW_T(btBoxShape, Ogre::MEMCATEGORY_GENERAL)(btVector3(thickness / 2, thickness / 2, length / 2));
	
	btVector3 localInertia(0, 0, 0);
	Ogre::Real mass = 10;
	Ogre::Real restitution = 0.6;
	Ogre::Real friction = 0.6;
	mCollisionShape->calculateLocalInertia(mass, localInertia);

//	Ogre::Quaternion ori = (Ogre::Vector3::NEGATIVE_UNIT_Z).getRotationTo(end - start);
	btTransform trans;
	trans.setIdentity();//.setRotation(btQuaternion(ori.x, ori.y, ori.z, ori.w));//
	trans.setOrigin(btVector3((end.x + start.x) / 2, (end.y + start.y) / 2, (end.z + start.z) / 2));
	mStartPos = start;
	mStartOri = Ogre::Quaternion::IDENTITY;
	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	mMotionState = OGRE_NEW_T(GirderMotionState, Ogre::MEMCATEGORY_GENERAL)(trans, mNode);

	btRigidBody::btRigidBodyConstructionInfo cInfo(mass, mMotionState, mCollisionShape, localInertia);
	
	mBody = OGRE_NEW_T(btRigidBody, Ogre::MEMCATEGORY_GENERAL)(cInfo);

	mBody->setContactProcessingThreshold(BT_LARGE_FLOAT);
	mBody->setWorldTransform(trans);
	mBody->setRestitution(restitution);
	mBody->setFriction(friction);

	PhysicsManager::getSingleton().getWorld()->addRigidBody(mBody);

	Ogre::Vector3 pivot(0, 0, length / 2);
	Ogre::Quaternion ori = (Ogre::Vector3::NEGATIVE_UNIT_Z).getRotationTo((end - start));
	pivot = ori * pivot;

	btVector3 pivotInA(pivot.x, pivot.y, pivot.z);

	btVector3 axisInA(1, 0, 0);
	if (anchor1 != NULL)
	{
		btVector3 pivotInB = anchor1->mBody->getCenterOfMassTransform().inverse()(mBody->getCenterOfMassTransform()(pivotInA));
		btVector3 axisInB(anchor1->mBody->getCenterOfMassTransform().getBasis().inverse()*(anchor1->mBody->getCenterOfMassTransform().getBasis() * axisInA));
		mConstraint = OGRE_NEW_T(btHingeConstraint, Ogre::MEMCATEGORY_GENERAL)(*mBody, *anchor1->mBody, pivotInA, pivotInB, axisInA, axisInB);
	}
	else
		mConstraint = OGRE_NEW_T(btHingeConstraint, Ogre::MEMCATEGORY_GENERAL)(*mBody, pivotInA, axisInA);
//	mConstraint = NULL;
	if (mConstraint != NULL)
	{
		mConstraint->setDbgDrawSize(btScalar(1.f));
		
		PhysicsManager::getSingleton().getWorld()->addConstraint(mConstraint);
	}
I have also defined a ground:

Code: Select all

	btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);
	btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-5,0)));
	btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
	btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
	mWorld->addRigidBody(groundRigidBody);
The above code works great, but if I add the following code to create another girder it crashes in the constraint solver

Code: Select all

girder = pm->createGirder(Ogre::Vector3(3, 5, 12), Ogre::Vector3(3, 5, 15), 0.3, girder);
Very much code and text here but please bare with me. As I said if I create a height field shape it crashes as soon as I step the world. I create it like this:

Code: Select all

	const std::vector<float> heights = mTerrainInfo->getHeightmapData();
	mTerrainHeights = OGRE_ALLOC_T(float, heights.size(), Ogre::MEMCATEGORY_GENERAL);
/*	memcpy(mTerrainHeights, &heights[0], heights.size());
*/
	for (size_t i = 0; i < heights.size(); i++)
		mTerrainHeights[i] = 0.0f;

	btHeightfieldTerrainShape *heightshape = OGRE_NEW_T(btHeightfieldTerrainShape, Ogre::MEMCATEGORY_GENERAL)(mTerrainInfo->getWidth(), mTerrainInfo->getHeight(), (void*)/*&mTerrainInfo->getHeightmapData()[0]*/mTerrainHeights, 1.0f, 1, true, false);
	heightshape->setUseDiamondSubdivision(false);
	btVector3 scale(TILESIZE / (VERTICES_PER_TILESIDE - 1), (WORLD_HEIGHT - OCEAN_FLOOR_HEIGHT), TILESIZE / (VERTICES_PER_TILESIDE - 1));


	heightshape->setLocalScaling(scale);

	mWorldCollisionShape = heightshape;
	if (mWorldCollisionShape == NULL)
		return;
	btVector3 minAabb, maxAabb;
	btTransform trans;
	trans.setIdentity();
	trans.setOrigin(btVector3(0, 0, 0));
	mWorldCollisionShape->getAabb(trans, minAabb, maxAabb);
	trans.setOrigin(btVector3(-minAabb.x(), -minAabb.y() + OCEAN_FLOOR_HEIGHT, -minAabb.z()));

	btDefaultMotionState* myMotionState = new btDefaultMotionState(trans);
	btRigidBody::btRigidBodyConstructionInfo cInfo(0, myMotionState, mWorldCollisionShape);
//	mWorld->addCollisionObject(mWorldCollisionShape);
	mWorldBody = OGRE_NEW_T(btRigidBody, Ogre::MEMCATEGORY_GENERAL)(cInfo);
	mWorld->debugDrawObject(trans, mWorldCollisionShape, btVector3(1.0f, 0.0f, 1.0f));
    mWorldBody->setRestitution(0.1f);
    mWorldBody->setFriction(0.8f);
	mWorld->addRigidBody(mWorldBody);
This looks a little dirty but there are actually two functions, one that creates the collision shape and one that creates the rigid body from it.

(I have intentionally set all values to 0.0f for debug purposes...)

Please help me figure out what is wrong here.

Many thanks!
Tunis
Posts: 5
Joined: Wed Jun 02, 2010 8:29 am

Re: Can't get it working

Post by Tunis »

Okay just for fun I downloaded Bullet 2.73 and did exactly the same as I did for 2.76. I used CMake 2.8 and generated the VC files (using VC 2008 professional) and then I built the libraries.

And now my girders work without any problems... Haven't tried with the height field yet as I read some topics about them not working in 2.73

What is going on with my 2.76 build?

Thanks!

Tunis
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Can't get it working

Post by Erwin Coumans »

When you compile the Bullet 2.76 demos (using cmake etc), do the demos run fine?

What platform, compiler do you use?
Thanks,
Erwin
Tunis
Posts: 5
Joined: Wed Jun 02, 2010 8:29 am

Re: Can't get it working

Post by Tunis »

Thank you for taking the time,

Yes the demos work as they should.

I'm running Windows XP Pro 32bit with Visual Studio Pro 2008.

Hope that helps

Thanks!

Tunis
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Can't get it working

Post by Erwin Coumans »

Try to reproduce the problem in one of the Bullet demos. If the Bullet demos work fine, compare the working TerrainDemo (using btHeightFieldShape) with your own btHeightFieldShape.

Also you might want to check out the debug drawer, and see if some of the data is corrupt. Finally, you could export the world to a .bullet file and try loading it into the Bullet/Demos/SerializeDemo and see if that works fine. See http://bulletphysics.org/mediawiki-1.5. ... ialization how to export a .bullet file.

Thanks,
Erwin
Tunis
Posts: 5
Joined: Wed Jun 02, 2010 8:29 am

Re: Can't get it working

Post by Tunis »

Thank you for your reply!

I have done some more testing. The heightfield worked in 2.73, go figure. But when I change from trimesh to heightfield in the vehicle demo in 2.76 the vehicle doesn't fall to the ground. In the attached image you can see what it looks like from the start.
bulletvehicle.JPG
It starts really high in the air and then it falls towards the ground for almost 30 seconds and then it falls through the heightfield.

I inserted my girders into the constraint demo and they worked good. I could create 11 attached bodys without any crashes or other things.

I hope you can find a solution to this.

Many thanks!

Tunis
You do not have the required permissions to view the files attached to this post.
Tunis
Posts: 5
Joined: Wed Jun 02, 2010 8:29 am

Re: Can't get it working

Post by Tunis »

I finally got it working and I think I know what was wrong. I can't explain why the vehicle demo heightfield didn't work though.

I'm using Ogre to render the scene and I allocated all Bullet objects by using OGRE_NEW_T and when I changed this to new all the problems disappeared. I don't know why and perhaps someone can explain that to me. But it is working now, the girders and the heightfield all work as expected!

Thank you for takning your time Erwin!

Tunis