Page 1 of 1

How to speed up the deserialization of 'btBvhTriangleMeshShape' object.

Posted: Fri May 21, 2021 10:23 am
by guasqui_act
Hello everyone!

I am trying to take advantage of the serialization/deserialization feature to speed up the time of constructing a btBvhTriangleMeshShape object but for some reason I do not get the result I would expect.

Without using serialization/deserialization, my btBvhTriangleMeshShape object is constructed as:

Code: Select all

	////
	//
	// Inputs are:
	//	x - matrix with x-component values
	//	y - matrix with y-component values
	//	z - matrix with z-component values
	//	nRows, nCols - number of rows and columns of the input x, y, and z matrixes
	//
	////
	
	// populating ground vertices
	const int totalVerts = nRows * nCols;
	btVector3 *groundVertices = new btVector3[totalVerts];
	for (int i = 0; i < nRows; i++)
	{
		for (int j = 0; j < nCols; j++)
		{
			groundVertices[i * nCols + j].setValue( x[i][j], y[i][j], z[i][j] );
		}
	}

	// populating ground indices
	const int totalTriangles = 2 * (nRows - 1) * (nCols - 1);
	const int numTriangleIndexes = totalTriangles * 3;
	int *groundIndices = new int[numTriangleIndexes];
	int index = 0;
	for (int i = 0; i < nRows - 1; i++)
	{
		for (int j = 0; j < nCols - 1; j++)
		{
			groundIndices[index++] = i * nCols + j;
			groundIndices[index++] = (i + 1) * nCols + j;
			groundIndices[index++] = i * nCols + j + 1;

			groundIndices[index++] = i * nCols + j + 1;
			groundIndices[index++] = (i + 1) * nCols + j;
			groundIndices[index++] = (i + 1) * nCols + j + 1;
		}
	}

	// constructing 'btBvhTriangleMeshShape'
	int vertStride = sizeof(btVector3);
	int indexStride = 3 * sizeof(int);
	btTriangleIndexVertexArray *indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, groundIndices, indexStride, totalVerts, (btScalar*)&groundVertices[0].x(), vertStride);
	btBvhTriangleMeshShape *groundShape = new btBvhTriangleMeshShape(indexVertexArrays, false);
Now, I am willing to speed up the construction of the btBvhTriangleMeshShape by serializing/deserializing the btBvhTriangleMeshShape object. The following code is how I serialize it:

Code: Select all

	btDefaultSerializer serializer;
	serializer.startSerialization();
	groundShape->serializeSingleShape( &serializer );
	serializer.finishSerialization();
	FILE* ff = fopen("my_ground_shape.bullet", "wb");
	if ( !ff )
	{
		printf("Unable to open file\n");
		return;
	}
	fwrite(serializer.getBufferPointer(), serializer.getCurrentBufferSize(), 1, ff);
	fclose(ff);
and the deserialization code is as follows:

Code: Select all

	btBulletWorldImporter importer(NULL);
	if ( !importer.loadFile("my_ground_shape.bullet") )
	{
		printf("Unable to load file\n");
		return;
	}
	int numShape = importer.getNumCollisionShapes();
	if (!numShape) {
		printf("No terrain info found in file\n");
		return;
	}
	btBvhTriangleMeshShape *groundShape = (btBvhTriangleMeshShape*)importer.getCollisionShapeByIndex(0);
Let's assume that the serialization process was done offline and therefore that 'my_ground_shape.bullet' file already exists. At this stage, I would expect a speed-up when constructing btBvhTriangleMeshShape object using the desirialization approach as opposed to doing this from scratch, but unfortunately it looks like there is no gain in terms of execution time.
My usual test case has nRows = nCols = 400 and has the construction of btBvhTriangleMeshShape object being repeated 40 to 50 times. With these parameters the first snippet of code (creating the triangle mesh and allocating btBvhTriangleMeshShape) takes around 10 seconds, while the deserialization approach takes about 23.5 seconds (more than double).

I am sure I am missing some implementation point but I really can't get why the deserialization is such an inefficient method here. Can anyone explain this and give me the right implementation to speed-up the construction of btBvhTriangleMeshShape object?

Thank you!
Pierluigi Guasqui