Can Bullet load previously computed collision data?

Beevik
Posts: 2
Joined: Fri Dec 14, 2007 12:16 am

Can Bullet load previously computed collision data?

Post by Beevik »

I assume that Bullet, like most physics and collision libraries, takes a considerable amount of time to compute the collision data for complex, mostly static worlds with many collision shapes. An example of such a world would be a large heightfield terrain with many buildings and other obstacles on the terrain. Does Bullet allow you to store the results of its collision computations to a data buffer and then load them later? That way, you wouldn't need to re-compute the collision data every time you initialized the world.

I couldn't find any functions in the libraries that appeared to do anything like this.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Can Bullet load previously computed collision data?

Post by Erwin Coumans »

Beevik wrote:I assume that Bullet, like most physics and collision libraries, takes a considerable amount of time to compute the collision data for complex, mostly static worlds with many collision shapes. An example of such a world would be a large heightfield terrain with many buildings and other obstacles on the terrain. Does Bullet allow you to store the results of its collision computations to a data buffer and then load them later? That way, you wouldn't need to re-compute the collision data every time you initialized the world.

I couldn't find any functions in the libraries that appeared to do anything like this.
Yes, the main computation is creation of the bounding volume hierarchy for triangle meshes, this happens in the btOptimizedBvh class.

btOptimizedBvh has methods to 'serialize' and 'deSerializeInPlace', to save and load the bounding volume hierarchy from memory:

Code: Select all

	/// Data buffer MUST be 16 byte aligned
	bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);

	///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
	static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
The Bullet/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp shows how to use this:

Code: Select all

/comment out the next line to read the BVH from disk (first run the demo once to create the BVH)
#define SERIALIZE_TO_DISK 1
#ifdef SERIALIZE_TO_DISK
	trimeshShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression);
	m_collisionShapes.push_back(trimeshShape);
	
	
	///we can serialize the BVH data 
	void* buffer = 0;
	int numBytes = trimeshShape->getOptimizedBvh()->calculateSerializeBufferSize();
	buffer = btAlignedAlloc(numBytes,16);
	bool swapEndian = false;
	trimeshShape->getOptimizedBvh()->serialize(buffer,numBytes,swapEndian);
	FILE* file = fopen("bvh.bin","wb");
	fwrite(buffer,1,numBytes,file);
	fclose(file);
	btAlignedFree(buffer);
	


#else

	trimeshShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false);

	char* fileName = "bvh.bin";

	FILE* file = fopen(fileName,"rb");
	int size=0;
	btOptimizedBvh* bvh = 0;

	if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) {        /* File operations denied? ok, just close and return failure */
		printf("Error: cannot get filesize from %s\n", fileName);
		exit(0);
	} else
	{

		fseek(file, 0, SEEK_SET);

		int buffersize = size+btOptimizedBvh::getAlignmentSerializationPadding();

		void* buffer = btAlignedAlloc(buffersize,16);
		int read = fread(buffer,1,size,file);
		fclose(file);
		bool swapEndian = false;
		bvh = btOptimizedBvh::deSerializeInPlace(buffer,buffersize,swapEndian);
	}

	trimeshShape->setOptimizedBvh(bvh);

#endif
Hope this helps,
Erwin
Beevik
Posts: 2
Joined: Fri Dec 14, 2007 12:16 am

Re: Can Bullet load previously computed collision data?

Post by Beevik »

Thanks Erwin. That's just what I was looking for.