Issues De-serializing names of objects

Mako_energy02
Posts: 171
Joined: Sun Jan 17, 2010 4:47 am

Issues De-serializing names of objects

Post by Mako_energy02 »

I am currently trying to grab a number of collision shapes that were generated in blender and saved to a .bullet file into a Collision shape container I made. I'm currently trying to use the btBulletWorldImporter class to load the file into memory and create the shapes. I'm not passing in a pointer to the bullet world as I don't want it to try and manipulate the world at all. My function for doing this looks like this:

Code: Select all

btBulletWorldImporter* Importer = new btBulletWorldImporter();
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()))
{
      std::stringstream logstream;
      logstream << "Failed to load file: " << FileName << " , in CollisionShapeManager::LoadAllShapesFromFile";
      World::GetWorldPointer()->LogAndThrow(Exception(logstream.str()));
      return;
}
for( Whole X = 0 ; X < Importer->getNumCollisionShapes() ; X++ )
{
      btCollisionShape* Shape = Importer->getCollisionShapeByIndex(X);
      String Name = Importer->getNameForPointer((void*)Shape);
[...]
The last line there causes a crash because the function returns NULL. This implies there is no name in there, however when making/exporting the shape the name was set to the shape. Furthermore when the same file is loaded with the Bullet Physics Editor the name appears just fine. I tried downloading and looking at the source for the Physics Editor and the project setup made absolutely no sense to me...so I couldn't find where/what code was used to load the shapes there. Why is the importer not grabbing the names of the shapes that I set?

Edit: I should clarify, the shape pointer I'm getting out of the Importer is valid, and not null or otherwise invalid.
Mako_energy02
Posts: 171
Joined: Sun Jan 17, 2010 4:47 am

Re: Issues De-serializing names of objects

Post by Mako_energy02 »

I've dug a bit deeper into this issue. I downloaded FileInspector, which was mentioned and linked to in another forum post about serialization. Upon inspecting the .bullet file all of the "m_name" fields for each shape was completely empty. So it would seem the names aren't being serialized in the first place, but this simply raises two other questions. First, why are the names visible in the Bullet Editor (listed in the scene graph panel) if they aren't being serialized? And second, Why aren't they being serialized? We're using the version of blender that is posted on the Bullet Editor download page with the exporter(that is listed as "includes names") built in. The names are being set inside blender and exported without any apparent issues. Until we load up .bullet file in FileInspector and see all name fields empty.

Could this be caused by a mismatch in bullet versions? Currently our game is using Bullet 2.77.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Issues De-serializing names of objects

Post by Erwin Coumans »

Blender possibly only serializes Object names (btCollisionObject or btRigidBody), not shape names.

Thanks,
Erwin
Mako_energy02
Posts: 171
Joined: Sun Jan 17, 2010 4:47 am

Re: Issues De-serializing names of objects

Post by Mako_energy02 »

That's a bit annoying. Before you responded I started looking into adding the names myself. Pretty much just de-serializing nameless shapes, and doing some very hacky checks since I know the unique parameters each shape has and re-serializing them with names I have provided. But this doesn't seem to work. Specifically I'm trying to serialize compound shapes.

When I pull them out of the original .bullet file provided by blender they are fine, just without names. I give them names and then use them(all in the same run of my application), and their behavior is fine. Before the application ends I re-serialize the shapes with their names. When I check the file in file inspector all the data inside appears to be correct, with the exception of the names...they still don't appear to have been set. If I attempt to de-serialize the newly generated .bullet file in another run of my application, it seems to only de-serialize the children of the compound shape, but not the compound shapes themselves. So I have ~20 box shapes, ~10 cylinder shapes, and 0 compound shapes in the importer, instead of the intended 2 compound shapes.

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);
            }
        }
Serializing:

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);
And I have attached the two bullet files generated.

Edit: Apparently .bullet extensions aren't allowed. :(