Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Wed Oct 27, 2010 5:02 am 
Offline

Joined: Sat Oct 23, 2010 9:52 am
Posts: 3
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.

Quote:
Unhandled exception at 0x00e8919d in chaosFrame.exe: 0xC0000005: Access violation reading location 0x02a22ae0.


The call stack looks like this:
Quote:
> 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:

Quote:
> 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.


Top
 Profile  
 
PostPosted: Wed Oct 27, 2010 6:12 am 
Offline

Joined: Sat Oct 23, 2010 9:52 am
Posts: 3
The problem apparently was as explained here: http://bulletphysics.org/Bullet/phpBB3/viewtopic.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.


Top
 Profile  
 
PostPosted: Tue Nov 09, 2010 8:08 am 
Offline

Joined: Fri Jun 04, 2010 11:33 am
Posts: 11
/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.

Top
 Profile  
 
PostPosted: Fri Nov 12, 2010 1:52 am 
Offline

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


Top
 Profile  
 
PostPosted: Sat Jan 22, 2011 2:36 am 
Offline

Joined: Fri Oct 29, 2010 1:37 am
Posts: 50
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[i];

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[i];
btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];

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.


Top
 Profile  
 
PostPosted: Sun Mar 06, 2011 1:42 pm 
Offline

Joined: Wed Sep 08, 2010 2:57 pm
Posts: 37
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)


Top
 Profile  
 
PostPosted: Tue Sep 13, 2011 4:22 am 
Offline

Joined: Fri Oct 29, 2010 1:37 am
Posts: 50
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


Top
 Profile  
 
PostPosted: Tue Jun 25, 2013 10:26 pm 
Offline

Joined: Thu Feb 09, 2012 2:39 am
Posts: 30
Is this fixed in the latest stable release?


Top
 Profile  
 
PostPosted: Fri Jul 19, 2013 1:46 am 
Offline

Joined: Fri Oct 29, 2010 1:37 am
Posts: 50
yup


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group