problem loading mesh from .bullet file

Physics APIs, Physics file formats, Maya, Max, XSI, Cinema 4D, Lightwave, Blender, thinkingParticles™ and other simulation tools, exporters and importers
Post Reply
sonofrage
Posts: 3
Joined: Sat Oct 23, 2010 9:52 am

problem loading mesh from .bullet file

Post by sonofrage »

Hello, i'm a beginner using bullet. I'm trying to create a simple scene in 3DS Max, export it to a .bullet file and simulate it by loading it through the "btBulletWorldImporter" class.

So far it works fine for simple shapes like box, sphere, but when i created a simple mesh shape for the static ground shape, i get an unhandled exception error as soon as the scene starts.
Unhandled exception at 0x00e8919d in chaosFrame.exe: 0xC0000005: Access violation reading location 0x02a22ae0.
The call stack looks like this:
> chaosFrame.exe!`btBvhTriangleMeshShape::processAllTriangles'::`2'::MyNodeOverlapCallback::processNode(int nodeSubPart, int nodeTriangleIndex) Line 299 + 0xb bytes C++
chaosFrame.exe!btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback * nodeCallback, unsigned short * quantizedQueryAabbMin, unsigned short * quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) Line 712 + 0x21 bytes C++
chaosFrame.exe!btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback * nodeCallback, const btVector3 & aabbMin, const btVector3 & aabbMax) Line 329 C++
chaosFrame.exe!btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback * callback, const btVector3 & aabbMin, const btVector3 & aabbMax) Line 329 C++
chaosFrame.exe!btCollisionWorld::debugDrawObject(const btTransform & worldTransform, const btCollisionShape * shape, const btVector3 & color) Line 1285 + 0x2a bytes C++
chaosFrame.exe!btCollisionWorld::debugDrawWorld() Line 1376 + 0x25 bytes C++
chaosFrame.exe!btDiscreteDynamicsWorld::debugDrawWorld() Line 121 C++
chaosFrame.exe!CsGame::Physics() Line 66 + 0x17 bytes C++
chaosFrame.exe!CsGame::Run() Line 224 C++
... etc.
If i disable debug drawing, the program runs for a while (a box falls down) and then crashes when it (presumably) collides with the mesh shape. The call stack then looks like:
> chaosFrame.exe!`btBvhTriangleMeshShape::processAllTriangles'::`2'::MyNodeOverlapCallback::processNode(int nodeSubPart, int nodeTriangleIndex) Line 299 + 0xb bytes C++
chaosFrame.exe!btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback * nodeCallback, unsigned short * quantizedQueryAabbMin, unsigned short * quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) Line 712 + 0x21 bytes C++
chaosFrame.exe!btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback * nodeCallback, const btVector3 & aabbMin, const btVector3 & aabbMax) Line 329 C++
chaosFrame.exe!btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback * callback, const btVector3 & aabbMin, const btVector3 & aabbMax) Line 329 C++
chaosFrame.exe!btConvexConcaveCollisionAlgorithm::processCollision(btCollisionObject * body0, btCollisionObject * body1, const btDispatcherInfo & dispatchInfo, btManifoldResult * resultOut) Line 197 + 0x2e bytes C++
chaosFrame.exe!btCollisionDispatcher::defaultNearCallback(btBroadphasePair & collisionPair, btCollisionDispatcher & dispatcher, const btDispatcherInfo & dispatchInfo) Line 268 + 0x28 bytes C++
chaosFrame.exe!btCollisionPairCallback::processOverlap(btBroadphasePair & pair) Line 224 + 0x21 bytes C++
chaosFrame.exe!btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback * callback, btDispatcher * dispatcher) Line 387 + 0x13 bytes C++
chaosFrame.exe!btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache * pairCache, const btDispatcherInfo & dispatchInfo, btDispatcher * dispatcher) Line 238 + 0x17 bytes C++
chaosFrame.exe!btCollisionWorld::performDiscreteCollisionDetection() Line 214 + 0x37 bytes C++
chaosFrame.exe!btDiscreteDynamicsWorld::internalSingleStepSimulation(float timeStep) Line 318 + 0xf bytes C++
chaosFrame.exe!btDiscreteDynamicsWorld::stepSimulation(float timeStep, int maxSubSteps, float fixedTimeStep) Line 281 + 0x19 bytes C++
chaosFrame.exe!CsGame::Physics() Line 60 + 0x2d bytes C++
chaosFrame.exe!CsGame::Run() Line 224 C++
... etc

The mesh shape I created in 3DS Max looks like this:
Image
I created a plane, converted it to editable poly and translated the vertices to create a distorted shape as shown. Then I added them to physics from the bullet control panel, and the simulation runs fine from within 3DS Max.

But the program crashes when I try to use the .bullet file. I even tried a much simpler mesh with only 16 vertices.

What am I doing wrong? Is there a specific set of steps I need to follow to generate meshes from 3DS Max? Please help.
sonofrage
Posts: 3
Joined: Sat Oct 23, 2010 9:52 am

Re: problem loading mesh from .bullet file

Post by sonofrage »

The problem apparently was as explained here: http://bulletphysics.org/Bullet/phpBB3/ ... php?t=5611

I created a bParse::btBulletFile in order to load the .bullet file from memory, and kept the file till the end of the scene's lifetime. that solved the problem.

Another question: do the meshes exported from 3DS Max have the bvh acceleration structure? would it be wise to group all the static geometry objects before exporting?

thanks.
Sauce
Posts: 11
Joined: Fri Jun 04, 2010 11:33 am

Re: problem loading mesh from .bullet file

Post by Sauce »

/offtopic: how are you exporting the mesh from 3dsmax? Last I checked the bullet plugins were only available for Maya.

If its not too much trouble would you also be able to confirm for me if this (clicky) is similar to the method you used?
Last edited by Sauce on Fri Nov 12, 2010 3:21 pm, edited 1 time in total.
VicariousEnt
Posts: 50
Joined: Fri Oct 29, 2010 1:37 am

Re: problem loading mesh from .bullet file

Post by VicariousEnt »

There's Dynamica for Max now too, check the download page.
VicariousEnt
Posts: 50
Joined: Fri Oct 29, 2010 1:37 am

Re: problem loading mesh from .bullet file

Post by VicariousEnt »

Ok, so I ended up running into this crash problem myself and decided to come up with a proper fix for it instead of a work around. The crash is basically from a sort of design flaw in the btGimpactTriangleMeshShape collision primitive. If you look at the GimpactTestDemo it illustrates how this class never takes ownership of its owns vertex and face index data. Ideally it should or should have an option to, but I wasn't about to rewrite any of the Bullet SDK.

Instead I modified the WorldImporter to make and mange copies of the btStridingMeshInterfaceData class which is where this data is stored. WorldImporter maintains another object array of these structures in my fix, and they are freed properly when deleteAllData() is called in the World Importer.

A bigger problem IMO is that static concave geometry should not be exported as btGimpactTriangleMeshShapes or btCompoundShapes. Currently individual static Triangle meshes are being created as btGimpactTriangleMeshShapes inside of btCompoundShapes and with a btRigidBody, when all they need (at least for games) is to be a btTriangleMesh or even better, a btOptimizedBvh. Anyways, I have a request list going in my own thread, I'll bring up that issue there.

Here is my fix for this crash, it is very simple to intergrate and is done in a way that is consistent with the existing code. The red bits are the new code that you need to add, the blue existing code....

To btBulletWorldImporter.h, add the following to the appropriate areas...

class btBulletWorldImporter
{
protected:

btAlignedObjectArray<btStridingMeshInterfaceData*> m_allocatedbtStridingMeshInterfaceDatas;

virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);


To btBulletWorldImporter.cpp add the following...

void btBulletWorldImporter::deleteAllData()
{


//add this to the very bottom of this function...

for (i=0;i<m_allocatedbtStridingMeshInterfaceDatas.size();i++)//-SE
{
btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas;

for(int a = 0;a < curData->m_numMeshParts;a++)
{
btMeshPartData* curPart = &curData->m_meshPartsPtr[a];
if(curPart->m_vertices3f)
delete [] curPart->m_vertices3f;

if(curPart->m_vertices3d)
delete [] curPart->m_vertices3d;

if(curPart->m_indices32)
delete [] curPart->m_indices32;

if(curPart->m_3indices16)
delete [] curPart->m_3indices16;

if(curPart->m_indices16)
delete [] curPart->m_indices16;
}
delete [] curData->m_meshPartsPtr;
delete curData;
}
m_allocatedbtStridingMeshInterfaceDatas.clear();

}


new function...

btStridingMeshInterfaceData* btBulletWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)//-SE
{
//create a new btGImpactMeshShapeData that is an exact copy of shapedata and store it in the WorldImporter
//as btGImpactMeshShapes do not retain ownership of their vertex and index data.
btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;

newData->m_scaling = interfaceData->m_scaling;
newData->m_numMeshParts = interfaceData->m_numMeshParts;
newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];

for(int i = 0;i < newData->m_numMeshParts;i++)
{
btMeshPartData* curPart = &interfaceData->m_meshPartsPtr;
btMeshPartData* curNewPart = &newData->m_meshPartsPtr;

curNewPart->m_numTriangles = curPart->m_numTriangles;
curNewPart->m_numVertices = curPart->m_numVertices;

if(curPart->m_vertices3f)
{
curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];
memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices);
}
else
curNewPart->m_vertices3f = NULL;

if(curPart->m_vertices3d)
{
curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];
memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices);
}
else
curNewPart->m_vertices3d = NULL;

int numIndices = curNewPart->m_numTriangles * 3;

if(curPart->m_indices32)
{
curNewPart->m_indices32 = new btIntIndexData[numIndices];
memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices);
}
else
curNewPart->m_indices32 = NULL;

if(curPart->m_3indices16)
{
curNewPart->m_3indices16 = new btShortIntIndexTripletData[numIndices];
memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * numIndices);
}
else
curNewPart->m_3indices16 = NULL;

if(curPart->m_indices16)
{
curNewPart->m_indices16 = new btShortIntIndexData[numIndices];
memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices);
}
else
curNewPart->m_indices16 = NULL;
}

m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);

return(newData);
}


last make these 2 changes to convertCollisionShape...

btCollisionShape* btBulletWorldImporter::convertCollisionShape( btCollisionShapeData* shapeData )
{
...
case GIMPACT_SHAPE_PROXYTYPE:
{
btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData;
if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
{

btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);
btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);// interfaceData used to be gimpactData->m_meshInterface
btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
...


That should be it, everything should work as you would expect and there shouldn't be any memory leaks. Sorry for the lack of indenting, I use tabs in my code and they never show up in php posts. I've tested this code but not with all types of vertex and index data. Please let me know if these changes cause any bugs or issues and I'll update this post if so.
EnlightenedOne
Posts: 37
Joined: Wed Sep 08, 2010 2:57 pm

Re: problem loading mesh from .bullet file

Post by EnlightenedOne »

This is an excellent fix :)

Thank you VicariousEnt, now I need to dig up the code I saw on converting a rigid body to a btBvhTriangleMeshShape and I am in serious buisness! 8)
VicariousEnt
Posts: 50
Joined: Fri Oct 29, 2010 1:37 am

Re: problem loading mesh from .bullet file

Post by VicariousEnt »

Dynamica is availabe for Max now.
EnlightenedOne wrote:This is an excellent fix :)

Thank you VicariousEnt, now I need to dig up the code I saw on converting a rigid body to a btBvhTriangleMeshShape and I am in serious buisness! 8)
The last release of Dyamica actually has code in it for this but a bug kept it from being exposed in the released build. If you're up to building the Maya Dynamica project yourself, change this line in collisionShapeNode.cpp...

fnEnumAttr.addField("BvhMesh", 6); <-- Line 71 in collisionShapeNode::initialize()

Change the 6 to a 7 and it will work. That change is necesary for the changes made just before release but has been fixed in the very latest trunk. See my issue page for more details...

http://code.google.com/p/dynamica/issues/detail?id=18
rraallvv
Posts: 30
Joined: Thu Feb 09, 2012 2:39 am

Re: problem loading mesh from .bullet file

Post by rraallvv »

Is this fixed in the latest stable release?
VicariousEnt
Posts: 50
Joined: Fri Oct 29, 2010 1:37 am

Re: problem loading mesh from .bullet file

Post by VicariousEnt »

yup
Post Reply