Deactivation

Zakalwe
Posts: 14
Joined: Mon Feb 04, 2008 5:23 pm

Deactivation

Post by Zakalwe »

Hi guys, I just started using bullet a little while ago.

Basically what I want is to do the following. Setup an environment made from a mesh of triangles. In the environment there will be a stack of boxes. Another box will fall on the stack. When a box stops moving there will be a callback to some of my own code. If an object starts moving again, another callback will call some of my own code.

I have done the following

1) Created a btBvhTriangleMeshShape for the world.
2) Created a btRigidBody for each box.

My code is pretty much copy and paste work from the demos, but I have two basic questions

1) Why do my boxes continuously jitter about? Why do they not deactivate eventually?
2) How do I add the desired callbacks?

Thanks!


Here's what I currently have.

Code: Select all

	//Load the world
	Object *O = new Object("sponza.tri");
	Objects.push_back(O);

	btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
	btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
	btVector3 worldAabbMin(O->tree->aabb.min.x -100, O->tree->aabb.min.y -100, O->tree->aabb.min.z -100);
	btVector3 worldAabbMax(O->tree->aabb.max.x +100, O->tree->aabb.max.y +100, O->tree->aabb.max.z +100);
	int maxProxies = 1024;
	btAxisSweep3* overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
	btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;	
	btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
	
	dynamicsWorld->setGravity(btVector3(0, 0, -100));

        /*
         * Create a BVH Mesha object from discrete triangles (the main static geometry)
         */
	int totalTriangles = Objects[0]->triangles.size();
	int totalVerts = totalTriangles * 3;
	btVector3 *m_vertices = new btVector3[totalVerts];
	int *gIndices = new int[totalTriangles*3];
	int vertStride = sizeof(btVector3);
	int indexStride = 3*sizeof(int);
	
	int index = 0;
	
	for (tri_vec_it c_tri = Objects[0]->triangles.begin(); c_tri != Objects[0]->triangles.end(); c_tri++) {
		for (int i = 0; i < 3; ++i) {
			Tri& t = *c_tri;
			Point& p = t[i];
			m_vertices[index].setValue(p.x, p.y, p.z);
			index++;
			gIndices[index] = index;
		}
		
	}
	
	btTriangleIndexVertexArray *m_indexVertexArrays = new btTriangleIndexVertexArray(
			totalTriangles,
			gIndices,
			indexStride,
			totalVerts,
			(btScalar*) &m_vertices[0].x(),
			vertStride);
	
	bool useQuantizedAabbCompression = true;
	btCollisionShape *groundShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression);
	
	
	btAlignedObjectArray<btCollisionShape*> collisionShapes;
	
	collisionShapes.push_back(groundShape);
	
	btTransform groundTransform;
	groundTransform.setIdentity();
	groundTransform.setOrigin(btVector3(0, 0, 0));
	
	{
		btScalar mass(0.);

		bool isDynamic = (mass != 0.f);
		
		btVector3 localInertia(0, 0, 0);
		if (isDynamic)
			groundShape->calculateLocalInertia(mass, localInertia);
		
		btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
		btRigidBody* body = new btRigidBody(rbInfo);
		
		
		//add the body to the dynamics world
		dynamicsWorld->addRigidBody(body);
	}
	
	
	//Load another object
	O = new Object("small_cube.tri");
        //cube starts off suspended in the air above stack of boxes
	O->offset.set(0.0, 0.0, 300);
	Objects.push_back(O);
	
	{
		//create a dynamic rigidbody

		btCollisionShape *colShape = new btBoxShape(btVector3( (O->tree->aabb.max.x - O->tree->aabb.min.x)/2.0f,
						(O->tree->aabb.max.y - O->tree->aabb.min.y)/2.0f,
						(O->tree->aabb.max.z - O->tree->aabb.min.z)/2.0f));
		//btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
		//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
		collisionShapes.push_back(colShape);
		
		
		/// Create Dynamic Objects
		btTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(btVector3(O->offset.x, O->offset.y, O->offset.z));
		
		btScalar mass(1.f);
		
		
		//rigidbody is dynamic if and only if mass is non zero, otherwise static
		bool isDynamic = (mass != 0.f);
		
		btVector3 localInertia(0, 0, 0);
		if (isDynamic)
			colShape->calculateLocalInertia(mass, localInertia);
		
		
		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
		btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia);
		btRigidBody* body = new btRigidBody(rbInfo);
		
		dynamicsWorld->addRigidBody(body);
	}
	
	
	//Sponza and Cube Loaded
	//Now to instance cube a few times...

	for (int x = 0; x < 5; ++x) {
		for (int z = 0; z < 5; ++z) {
			O = new Object();
			O->tree = Objects[1]->tree;
			O->offset.set(x * 10, 0.0, (z * 10) + 10);
			Objects.push_back(O);
			
			{
				//create a dynamic rigidbody

				btCollisionShape *colShape = new btBoxShape(btVector3( (O->tree->aabb.max.x - O->tree->aabb.min.x)/2.0f,
								(O->tree->aabb.max.y - O->tree->aabb.min.y)/2.0f,
								(O->tree->aabb.max.z - O->tree->aabb.min.z)/2.0f));
				//btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
				//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
				collisionShapes.push_back(colShape);
				
				
				/// Create Dynamic Objects
				btTransform startTransform;
				startTransform.setIdentity();
				startTransform.setOrigin(btVector3(O->offset.x, O->offset.y, O->offset.z));
				
				btScalar mass(1.f);
				
				
				//rigidbody is dynamic if and only if mass is non zero, otherwise static
				bool isDynamic = (mass != 0.f);
				
				btVector3 localInertia(0, 0, 0);
				if (isDynamic)
					colShape->calculateLocalInertia(mass, localInertia);
				
				
				//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
				btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
				btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia);
				btRigidBody* body = new btRigidBody(rbInfo);
				dynamicsWorld->addRigidBody(body);
			}
		}
		
	}
	
Zakalwe
Posts: 14
Joined: Mon Feb 04, 2008 5:23 pm

Re: Deactivation

Post by Zakalwe »

Anyone? Any hints at all?
User avatar
detox
Posts: 12
Joined: Wed Nov 22, 2006 6:52 pm
Location: Ohio, USA

Re: Deactivation

Post by detox »

Nothing jumps out at me.

I see you set gravity to 100, and you are using 1.0 for most (all?) of your masses. Maybe try 10 or so for your gravity setting? (9.81...)

How do the sizes of the boxes compare to the sizes of the objects they are resting on?

How often/fast are you stepping the Bullet world simulation?
Zakalwe
Posts: 14
Joined: Mon Feb 04, 2008 5:23 pm

Re: Deactivation

Post by Zakalwe »

Thanks for the reply :)

I upped the mass to 100 with no changes. I call

dynamicsWorld->stepSimulation(time, 10); once per frame. The simulation runs at around 30fps.

The world is around 1000x100. The boxes are about 50x50
Zakalwe
Posts: 14
Joined: Mon Feb 04, 2008 5:23 pm

Re: Deactivation

Post by Zakalwe »

I'm not sure HOW i fixed it, but it works now after scrapping the old code and writing new code from scratch.

Now does anyone know how to add those deactivation callbacks?