serializing / deserializing btBvhTriangleShape

Post Reply
Sauce
Posts: 11
Joined: Fri Jun 04, 2010 11:33 am

serializing / deserializing btBvhTriangleShape

Post by Sauce »

I'm writing a tool to convert an Ogre mesh file to a bullet file for use in our game. Problem is, I can't for the life of me get serializing / deserializing to work as expected; the triangle data produced is just plain wrong. I've been stepping through bullet all day long trying to find the cause, and came to the conclusion that the triangle data was getting deleted as the btWorldImporter went out of scope (it deletes data it did not allocate!) so I instead allocated the world importer on the heap and (for testing purposes) never delete it - yet when I view the deserialized mesh by enabling debug draw, I get a series of lines going from the origin to infinity in all directions. I read elsewhere on the forum that Bullet never makes a copy of the data it reads from the .bullet file, so I instead filled a buffer from the file myself, and ensured that the data was not deleted prematurely, but this didn't help either.

Image

Well, I think it's about time for some code - beware of the leaks; this is purely for testing purposes.

Serialize

Code: Select all

void OgreMeshCollisionHull::serialize(std::string const &path)
{
	std::string directory, fileName, extension;
	size_t slashPos = path.find_last_of("\\/");
	if(slashPos != std::string::npos)
	{
		++slashPos;
		size_t dotPos = path.find_last_of('.');

		directory = path.substr(0, slashPos);
		fileName = path.substr(slashPos, dotPos - slashPos);
		extension = path.substr(dotPos, std::string::npos);
	}

	//Create a large enough buffer. There is no method to pre-calculate the buffer size yet.
	const size_t byteCount = 1024 * 1024 * 5;

	btDefaultSerializer *pSerializer = new btDefaultSerializer(byteCount);
	pSerializer->registerNameForPointer(m_pCollisionShape, fileName.c_str());

	pSerializer->startSerialization();
	m_pCollisionShape->serializeSingleShape(pSerializer);
	pSerializer->finishSerialization();

	std::fstream file;
	file.open(path.c_str(), std::ios_base::out | std::ios_base::binary);
	file.write((const char *)pSerializer->getBufferPointer(), pSerializer->getCurrentBufferSize());
	file.close();

	delete pSerializer;
	pSerializer = 0;
}
Deserialize

Code: Select all

void OgreMeshCollisionHull::deserialize(BulletPhysicsWorld &physics, std::string const &path)
{
	std::fstream file;
	file.open(path.c_str(), std::ios_base::in | std::ios_base::binary | std::ios_base::ate);
	if(file)
	{
		m_byteCount = file.tellg();
		file.seekg(0, std::ios::beg);

		m_pData = new char[m_byteCount];
		file.read(m_pData, m_byteCount);
		file.close();
	}

	//Leaks ahoy!
	btBulletWorldImporter *pImporter = new btBulletWorldImporter;
	if(pImporter->loadFileFromMemory(m_pData, m_byteCount))
	{
		int numShapes = pImporter->getNumCollisionShapes();
		if(numShapes >= 1)
		{
			m_pCollisionShape = (btBvhTriangleMeshShape*)new char[sizeof(btBvhTriangleMeshShape)];
			memcpy((void*)m_pCollisionShape, (void*)pImporter->getCollisionShapeByIndex(0), sizeof(btBvhTriangleMeshShape));
			btRigidBody::btRigidBodyConstructionInfo constructionInfo(0.0f, NULL, m_pCollisionShape);
			physics.addRigidBody(constructionInfo);
		}
	}
}
I can verify that the mesh strider is producing valid data (it's this one from the Ogre wiki), as the BVH triangle mesh appears just fine prior to serialization. Is there anything obvious I'm missing? This is driving me nuts.

Note: I have tried this with the simplest mesh I could come up with - a tetrahedron, but that was no help. I've attached the bullet file from the screenshot if anyone wants to take a look at it (it's meant to be a tank trap)
Attachments

[The extension bullet has been deactivated and can no longer be displayed.]

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

Re: serializing / deserializing btBvhTriangleShape

Post by Erwin Coumans »

Please use the btDiscreteDynamicsWorld::serialize when using the btBulletWorldImporter.

Your .bullet file contains incomplete date, no rigid bodies etc, when viewed with the file inspector:
tanktrap.jpg
tanktrap.jpg (139.2 KiB) Viewed 7944 times
Thanks,
Erwin
Sauce
Posts: 11
Joined: Fri Jun 04, 2010 11:33 am

Re: serializing / deserializing btBvhTriangleShape

Post by Sauce »

I don't understand - you yourself state in this thread that btCollisionShape::serialize() should be used for serializing a single shape. Is this no longer the case?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: serializing / deserializing btBvhTriangleShape

Post by Erwin Coumans »

Sauce wrote:I don't understand - you yourself state in this thread that btCollisionShape::serialize() should be used for serializing a single shape. Is this no longer the case?
If you choose to manually serialize individual collision shapes, you cannot use the btBulletWorldImporter to load the .bullet file. In that case, you will need to manually deserialize and deal with the complicated/low level data structures.

It is easier to first get the btDiscreteDynamicsWorld serialization and btBulletWorldImporter working first.
Thanks,
Erwin
Sauce
Posts: 11
Joined: Fri Jun 04, 2010 11:33 am

Re: serializing / deserializing btBvhTriangleShape

Post by Sauce »

Erwin Coumans wrote:
Sauce wrote:I don't understand - you yourself state in this thread that btCollisionShape::serialize() should be used for serializing a single shape. Is this no longer the case?
If you choose to manually serialize individual collision shapes, you cannot use the btBulletWorldImporter to load the .bullet file. In that case, you will need to manually deserialize and deal with the complicated/low level data structures.

It is easier to first get the btDiscreteDynamicsWorld serialization and btBulletWorldImporter working first.
Thanks,
Erwin
So if I create an empty physics world, add a rigid body with the triangle mesh, then serialize the world, will I be able to deserialize just the collision shape I need?
Sauce
Posts: 11
Joined: Fri Jun 04, 2010 11:33 am

Re: serializing / deserializing btBvhTriangleShape

Post by Sauce »

I tried adding a rigid body to the physics world and serializing the world, but the mesh data still does not load correctly. Can someone verify whether or not this is valid data? (file attached) I had a look using the file inspector you linked me but the btVector3FloatData doesn't seem to be correct. If you take a look at the following screenshot (the first 4 entries under btVector3FloatData) you will notice that there appears to be a padding issue.

Image

-431602080.000000 is 0xCDCDCDCD in hex, ie. uninitialised memory. It should be the 4th unused component of a 3 component SIMD vector, but as you can see from the screenshot it's offset by 4 bytes for every vector. Is this a bug in bullet?
Attachments

[The extension bullet has been deactivated and can no longer be displayed.]

Post Reply