Problem colliding trimeshes

nerdjock
Posts: 4
Joined: Thu Oct 15, 2009 10:31 am

Problem colliding trimeshes

Post by nerdjock »

Hi guys,

I wonder if anyone could help me. I am integrating bullet into my renderer. i require the ability to collide trimeshes with trimeshes. I am using the
btTriangleIndexVertexArray and btBvhTriangleMeshShape classes to read in my trimeshes. However, I have not had any luck colliding them.
As I advance the simulation, the objects do move, however, no collision.

Thinking that I was creating my btTriangleIndexVertexArray incorrectly, I copied the mesh directly into two arrays, very similarly to the code in many of the example demos such as ConcacePhysicsDemo, and tried colliding. The code is, as far as I can see, basically identical to the demo, yet they do not collide. Interestingly, if I change one of the meshes to a btBoxShape (I am in fact using a mesh of a box for debugging, and I set the btBoxShape to be identical in size), they collide fine.

I have ruled out my renderer being at fault because I am manually watching the world positions.

Here is my code (was put together from the HelloWorld demo):

Code: Select all

btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();

	///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
	btCollisionDispatcher* dispatcher = new	btCollisionDispatcher(collisionConfiguration);

	///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
	btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();

	///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
	btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
	btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
	dynamicsWorld->setGravity(btVector3(0,-10,0));

	///create a few basic rigid bodies
	//keep track of the shapes, we release memory at exit.
	//make sure to re-use collision shapes among rigid bodies whenever possible!
	btAlignedObjectArray<btCollisionShape*> collisionShapes;

	// Here's where we manually set the mesh
	int vertStride = sizeof(btVector3);
	int indexStride = 3*sizeof(int);

	const int totalTriangles = 12;
	const int totalVerts = 8;

	btVector3 * gVertices = new btVector3[totalVerts];
	int* gIndices = new int[totalTriangles*3];

	for(i = 0; i < totalTriangles*3; i++)
	{
		gIndices[i] = sc.mod[0].triangles[i];
	}

	for(i = 0; i < totalVerts; i++)
	{
		gVertices[i].setX(sc.mod[0].vertices[i].coords[0]);
		gVertices[i].setY(sc.mod[0].vertices[i].coords[1]);
		gVertices[i].setZ(sc.mod[0].vertices[i].coords[2]);
	}

	btTriangleIndexVertexArray* m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles,gIndices,indexStride, totalVerts,(btScalar*) &gVertices[0].x(),vertStride);
	bool useQuantizedAabbCompression = true;

	btVector3 aabbMin(-1,-1,-1),aabbMax(1,1,1);

	btBvhTriangleMeshShape* trimeshShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
	btBvhTriangleMeshShape* trimeshShape2  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
	//btCollisionShape* trimeshShape = new btBoxShape(btVector3(btScalar(1.),btScalar(1.),btScalar(1.)));
	//btCollisionShape* trimeshShape2 = new btBoxShape(btVector3(btScalar(1.),btScalar(1.),btScalar(1.)));

	collisionShapes.push_back(trimeshShape);
	collisionShapes.push_back(trimeshShape2);


	/// Create Dynamic Objects
	btTransform startTransform;
	btTransform startTransform2;
	startTransform.setIdentity();
	startTransform2.setIdentity();

	btScalar mass(1.0f);
	btScalar mass2(0.0f);

	// Setting this for dynamic shapesss
	btVector3 localInertia(0,0,0);
	btVector3 localInertia2(0,0,0);

	trimeshShape->calculateLocalInertia(mass,localInertia);
	trimeshShape2->calculateLocalInertia(mass2,localInertia2);

	startTransform.setOrigin(btVector3(0,10,0));
	startTransform2.setOrigin(btVector3(0,0,0));

	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
	btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,trimeshShape,localInertia);
	sc.mod[0].rigid = new btRigidBody(rbInfo);
	dynamicsWorld->addRigidBody(sc.mod[0].rigid);
	sc.mod[0].rigid->getAabb(aabbMin, aabbMax);

	for(i = 0; i < 3; i++)
	{
		sc.mod[0].bounding_box.min[i] = aabbMin.m_floats[i];
		sc.mod[0].bounding_box.max[i] = aabbMax.m_floats[i];
	}

	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	btDefaultMotionState* myMotionState2 = new btDefaultMotionState(startTransform2);
	btRigidBody::btRigidBodyConstructionInfo rbInfo2(mass2,myMotionState2,trimeshShape2,localInertia2);
	sc.mod[1].rigid = new btRigidBody(rbInfo2);
	dynamicsWorld->addRigidBody(sc.mod[1].rigid);
	sc.mod[1].rigid->getAabb(aabbMin, aabbMax);
sc.mod[] is my array of models which stores rendering and physics info. Then to advance the simulation I have:

Code: Select all

dynamicsWorld->stepSimulation(1.f/60.f,10);

		for(j = 0; j < dynamicsWorld->getNumCollisionObjects(); j++)
		{
			btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
			btRigidBody* body = btRigidBody::upcast(obj);

			if (body && body->getMotionState())
			{
				btTransform trans;
				body->getMotionState()->getWorldTransform(trans);
				printf("world pos = %f,%f,%f\n",float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ()));

				// Update AABB, copy for renderer
				sc.mod[j].rigid->getAabb(aabbMin, aabbMax);
				sc.mod[j].bounding_box.min[0] = aabbMin.m_floats[0];
				sc.mod[j].bounding_box.min[1] = aabbMin.m_floats[1];
				sc.mod[j].bounding_box.min[2] = aabbMin.m_floats[2];

				sc.mod[j].bounding_box.max[0] = aabbMax.m_floats[0];
				sc.mod[j].bounding_box.max[1] = aabbMax.m_floats[1];
				sc.mod[j].bounding_box.max[2] = aabbMax.m_floats[2];
			}
		}
Any help would be greatly appreciated.

Cheers.
nerdjock
Posts: 4
Joined: Thu Oct 15, 2009 10:31 am

Re: Problem colliding trimeshes

Post by nerdjock »

Problem Solved. For the benefit of anyone else with the same problem, btBvhTriangleMeshShape only intended for static meshes, so collisions between them are ignored, but collisions between them and btBoxShape work.