Bullet crashes when meshes collide

hydrowolfy
Posts: 1
Joined: Thu May 13, 2010 2:03 am

Bullet crashes when meshes collide

Post by hydrowolfy »

Currently in our project we are having issues with our collision shapes. We have two functions that'll get the mesh from Ogre(the Ogre Robot for testing) and create it into a collision shape, one for static bodies, and one for dynamic bodies. For the dynamic bodies we are making them into a convex hull (btConvexHullShape), and for static bodies we are making them into a triangle mesh (btBvhTriangleMeshShape). The problem we are having right now is when any static body and dynamic body exist in the world at the same time, it'll result in a crash.

Code: Select all

        #1 6D390834 btQuantizedBvh::walkStacklessQuantizedTree(this=0x1704090, nodeCallback=0x22f890, 

        quantizedQueryAabbMin=0x22f820, quantizedQueryAabbMax=0x22f810, startNodeIndex=0, endNodeIndex=615) 

        (btQuantizedBvh.cpp:712) 

        #2 6D38FABF btQuantizedBvh::reportAabbOverlappingNodex(this=0x1704090, nodeCallback=0x22f890, 

        aabbMin=..., aabbMax=...) (btQuantizedBvh.cpp:328)

        #3 6D36527C btBvhTriangleMeshShape::processAllTriangles(this=0x16e8540, callback=0x1678ffc, 

        aabbMin=..., aabbMax=...) (btBvhTriangleMeshShape.cpp:323)

        #4 6D3A53E0 btConvexConcaveCollisionAlgorithm::processCollision(this=0x1678ff0, body0=0x16e08b0, 

        body1=0x1717e10, dispatchInfo=..., resultOut=0x22f9a0) (btConvexConcaveCollisionAlgorithm.cpp:197)

        #5 6D36DA2D btCollisionDispatcher::defaultNearCallback(collisionPair=..., dispatcher=..., 

        dispatchInfo=...) (btCollisionDispatcher.cpp:268)

        #6 6D3F4E8A btCollisionPairCallback::processOverlap(this=0x22fb00, pair=...) 

        (btCollisionDispatcher.cpp:224)

        #7 6D3A6FD7 btHashedOverlappingPairCache::processAllOverlappingPairs(this=0x1675d50, 

        callback=0x22fb00, dispatcher=0x1676eb8) (btOverlappingPairCache.cpp:387)

        #8 6D36D882 btCollisionDispatcher::dispatchAllCollisionPairs(this=0x1676eb8, pairCache=0x1675d50, 

        dispatchInfo=..., dispatcher=0x1676eb8) (btCollisionDispatcher.cpp:238)

        #9 6D37A72F btCollisionWorld::performDiscreteCollisionDetection(this=0x1676078) 

        (btCollisionWorld.cpp:214)

        #10 6D3762EB btDiscreteDynamicsWorld::internalSingleStepSimulation(this=0x1676078, 

        timeStep=0.00249999994) (btDiscreteDynamicsWorld.cpp:318)

        #11 6D34FE1E btSoftRigidDynamicsWorld::internalSingleStepSimulation(this=0x1676078, 

        timeStep=0.00249999994) (btSoftRigidDynamicsWorld.cpp:61)

        #12 6D376142 btDiscreteDynamicsWorld::stepSimulation(this=0x1676078, timeStep=0, maxSubSteps=1, 

        fixedTimeStep=0.00249999994) (btDiscreteDynamicsWorld.cpp:281)

        #13 6D34E4A6 PhysWorld::DoMainLoopPhysics(this=0x446020, TimeElapsed=@0x22fdd4) (physworld.cpp:463)

        #14 6D34E118 PhysWorld::MainLoop(this=0x446020) (physworld.cpp:398)

        #15 00401708 main(argc=1, argv=0x3e9058) (gamebase.cpp:60)
Above is our call stack of the crash. It seems to us that it's registering a collision between the objects even though we place them far enough apart where that shouldn't happen. It also occured to us that the collision shape may be much larger then the ogre mesh, so we attempted to reduce the local scaling on the collision shape. We reduced it to such an extent where two dynamic bodies can be placed on top of each other and there be no collision, but add in (and apply the same scaling) a static body and it'll still crash. This seems to somehow be related to the classes we use for the collision shapes. Setting a convex hull shape as static doesn't cause a crash, even when a second dynamic object is added as a convex hull and they come in contact.

Prior to the crashes we were making everything as a convex hull, 2 static, and 2 dynamic. The dynamic bodies regardless of where we set their initial location in their motion state always got set back to origin(0,0,0), and they still do(another issue we want to ask about). The two dynamic bodies flew apart as one would expect when physics bodies overlap as such. Adding two static bodies (one above and one below) results in one actor flying to the right at high speed, and the other actor moving slightly to the left and then coming to rest(the graphical representations don't line up with this behavior at all, as far as can be seen, they are floating in the air).

We're not sure how to pursue this further, and are in need of help or insights on a fix for this, any sort of advice would be fully appreciated! thanks. oh! also, here's the functions in question.

Code: Select all

btTriangleMesh* ActorBase::CreateTrimesh()
{
    // Get the mesh from the entity
    Ogre::MeshPtr myMesh = entity->getMesh();

    // Get the submesh and associated data
    Ogre::SubMesh* subMesh = myMesh->getSubMesh(0);
    Ogre::IndexData*  indexData = subMesh->indexData;
    Ogre::VertexData* vertexData = subMesh->vertexData;

    // Get the position element
    const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

    // Get a pointer to the vertex buffer
    Ogre::HardwareVertexBufferSharedPtr vBuffer = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());

    // Get a pointer to the index buffer
    Ogre::HardwareIndexBufferSharedPtr iBuffer = indexData->indexBuffer;

    // Get the number of triangles
    unsigned int triCount = indexData->indexCount/3;

    // Allocate space for the vertices and indices
    Ogre::Vector3* vertices = new Ogre::Vector3[vertexData->vertexCount];
    unsigned long* indices  = new unsigned long[indexData->indexCount];

    // Lock the vertex buffer (READ ONLY)
    unsigned char* vertex =   static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
    float* pReal = NULL;
    for (size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vBuffer->getVertexSize() )
    {
        posElem->baseVertexPointerToElement(vertex, &pReal);
        Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
        vertices[j] = pt;
    }
    vBuffer->unlock();
    size_t index_offset = 0;
    bool use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

    // Lock the index buffer (READ ONLY)
    unsigned long* pLong = static_cast<unsigned long*>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
    unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);

    if (use32bitindexes)
    {
        for (size_t k = 0; k < triCount*3; ++k)
        {
            indices[index_offset++] = pLong[k];
        }
    }
    else
    {
        for (size_t k = 0; k < triCount*3; ++k)
        {
         indices[index_offset++] = static_cast<unsigned long>(pShort[k]);
        }
    }
    iBuffer->unlock();

    // We now have vertices and indices ready to go

    // The Bullet triangle mesh
    btTriangleMesh* trimesh = new btTriangleMesh(use32bitindexes);

    // Setup the tri mesh
    btVector3 vert0, vert1, vert2;
    int i=0;

    // For every triangle
    for (unsigned int y=0; y<triCount; y++)
    {
        // Set each vertex
        vert0.setValue(vertices[indices[i]].x, vertices[indices[i]].y, vertices[indices[i]].z);
        vert1.setValue(vertices[indices[i+1]].x, vertices[indices[i+1]].y, vertices[indices[i+1]].z);
        vert2.setValue(vertices[indices[i+2]].x, vertices[indices[i+2]].y, vertices[indices[i+2]].z);

        // Add it into the trimesh
        trimesh->addTriangle(vert0, vert1, vert2);

        // Increase index count
        i+=3;
    }
    delete[] vertices;
    delete[] indices;

    return trimesh;
}


void ActorRigid::CreateShapeFromMeshDynamic()
{
    delete Shape;

    btTriangleMesh *pshape = this->CreateTrimesh();
    btConvexShape *tmpshape = new btConvexTriangleMeshShape(this->CreateTrimesh());
    btShapeHull *hull = new btShapeHull(tmpshape);
    btScalar margin = tmpshape->getMargin();
    hull->buildHull(margin);
    //Shape=hull;
    tmpshape->setUserPointer(hull);
    btConvexHullShape* convexShape = new btConvexHullShape();
    for (int b=0;b<hull->numVertices();b++)
    {
        convexShape->addPoint(hull->getVertexPointer()[b]);
    }
    delete tmpshape;
    delete hull;
    delete pshape;
    Shape = convexShape;
    //this->Shape->setLocalScaling(btVector3(0.00001,0.00001,0.00001));
    this->physrigidbody->setCollisionShape(this->Shape);
}


void ActorRigid::CreateShapeFromMeshStatic()
{
    delete Shape;

    btTriangleMesh *pshape = this->CreateTrimesh();
    btBvhTriangleMeshShape *tmpshape = new btBvhTriangleMeshShape(pshape,true);
    this->Shape=tmpshape;
    //this->Shape->setLocalScaling(btVector3(0.00001,0.00001,0.00001));
    this->physrigidbody->setCollisionShape(this->Shape);
    delete pshape;
}
THESPHINX
Posts: 1
Joined: Wed Jul 21, 2010 3:37 pm

Re: Bullet crashes when meshes collide

Post by THESPHINX »

You should check if your meshes don't have too many stored vertices cause it's not recommended to build mesh Shapes with more then 100 vertices. It degrades the collision detection performance but doesn't make Bullet crash though. Try to make some test with meshes of less then 100 vertices and then check if the crash still occurs.