What I need is a bullet file with the compound shapes(crafted in blender by an artist) that have their names serialized, so I can just load the file, know exactly where each shape has to go and run the game. First I found out blender doesn't serialize names for shapes, only RigidBodies(As Erwin suggested in the other post). So I set out to add names to them myself. De-serializing the .bullet file provided by blender, registering names for the shapes and re-serializing them. Not only does this completely not work(both according to file inspector and according to tests attempting to de-serialize the new file), but when I try to use the compound shapes in the newly made bullet file, they are not there...only their children are. Which renders the file essentially useless. The compound shape data does appear in File Inspector, but the compound shape itself never gets de-serialized. Next I saw a forum post from Erwin a while back that said the importer is meant to only be used in conjunction with a full world Serialize. If you want to de-serialize individual things, you have to write your own code similar to that of the world importer. So the last two days I've done exactly that. However I get the exact same results as using the bullet world importer, PLUS the physics seems different. It's subtle but objects don't rotate as much, seem slower in general. I have no idea what in the collision shapes could be causing that.
I have even upgraded from Bullet 2.77 to 2.78 just because I was hoping some serialization improvement was made that would solve this issue. No such luck. So now I'm at a loss and to say I've frustrated at the amount of time I've spent trying to get something simple (a name on a shape ffs) would be an understatement.
Once again, here is the relevant code I am using:
Deserializing:
Code: Select all
btBulletWorldImporter Importer;
Ogre::DataStreamPtr Stream = Ogre::ResourceGroupManager::getSingleton().openResource(FileName,Group);
char* buffer = new char[Stream->size()];
Stream->read((void*)buffer, Stream->size());
if(!Importer.loadFileFromMemory(buffer, Stream->size()))
{
[throw exception]
}
delete[] buffer;
for( Whole X = 0 ; X < Importer.getNumCollisionShapes() ; ++X )
{
btCollisionShape* Shape = Importer.getCollisionShapeByIndex(X);
const char* MaybeAName = Importer.getNameForPointer((void*)Shape);
String Name;
if(MaybeAName)
{
Name = String(MaybeAName);
CollisionShapeManager::iterator it = CollisionShapes.find(Name);
if(it != CollisionShapes.end())
{
CollisionShape* NewShape = WrapShape(Name,Shape);
CollisionShapes[Name] = NewShape;
}
}else{
static Whole NameCount = 0;
Name = String("Unnamed")+=ToString(NameCount++);
CollisionShape* NewShape = WrapShape(Name,Shape);
UnnamedShapes.insert(NewShape);
}
}
Code: Select all
btDefaultSerializer* BulletSerializer = new btDefaultSerializer(1024*1024*5);
BulletSerializer->startSerialization();
for( std::map<String,CollisionShape*>::iterator it = CollisionShapes.begin() ; it != CollisionShapes.end() ; it++ )
{
CollisionShape* Shape = (*it).second;
BulletSerializer->registerNameForPointer((void*)Shape->GetBulletShape(),(*it).first.c_str());
int len = Shape->GetBulletShape()->calculateSerializeBufferSize();
btChunk* chunk = BulletSerializer->allocate(len,1);
const char* structType = Shape->GetBulletShape()->serialize(chunk->m_oldPtr, BulletSerializer);
BulletSerializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,Shape->GetBulletShape());
}
BulletSerializer->finishSerialization();
FILE* f2 = fopen(FileName.c_str(),"wb");
fwrite(BulletSerializer->getBufferPointer(),BulletSerializer->getCurrentBufferSize(),1,f2);
fclose(f2);