Constructing a btBvhTriangleMeshShape is very slow

Razorstorm
Posts: 4
Joined: Sat Feb 23, 2013 9:30 pm

Constructing a btBvhTriangleMeshShape is very slow

Post by Razorstorm »

I am building a voxel engine with bullet physics. I separated my voxels into chunks to batch up the render calls.

Each chunk's physics is handled by a btBvhTriangleMeshShape that is constructed through the vertices and indices.

Each time the user breaks a voxel, I modify the vertex and index array and construct a new btBvhTriangleMeshShape:

Code: Select all

btBvhTriangleMeshShape* mShape = new btBvhTriangleMeshShape(mTriMesh, useQuantizedAABB);
However, this takes ~400 milliseconds, which is too high latency.

Am I doing something wrong?

I also tried to turn off buildbvh option

Code: Select all

btBvhTriangleMeshShape* mShape = new btBvhTriangleMeshShape(mTriMesh, useQuantizedAABB, false);
but ray casts become too slow
RedToasty
Posts: 7
Joined: Wed Jan 18, 2012 9:54 am

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by RedToasty »

How big is each chunk? I assume you're only adding the exposed faces?

The best solution would obviously be making a custom shape, rather than using a trimesh. You're always going to have potentially thousands of polys per chunk otherwise. Whereas a few hundred octreed up AABBs is always going to be a lot faster.

Splitting the mesh into islands of convex hulls seems to work well.
Razorstorm
Posts: 4
Joined: Sat Feb 23, 2013 9:30 pm

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by Razorstorm »

The chunk sizes are 32x32x32 at the moment (but this can be easily modified).

I just took a look into btConvexHull and from the descriptions I found it should do what I want.

Edit: I tried to convert the mesh into a list of points and add them to the btConvexHull. This process, however, is extremely slow.

I tried 2 methods:

A) Iterate through my list of vertices and add them as points to the btConvexHull one by one:

Code: Select all

mCollisionShape = new OgreBulletCollisions::ConvexHullCollisionShape();
for( int i = 0; i < mVertices->size() ; i++)
{
    dynamic_cast<OgreBulletCollisions::ConvexHullCollisionShape* >(mCollisionShape)->addPoint(vertexArray[i]);
}
This takes ~10,000 - ~50,000 ms

B) Instead of storing an array of Vector3 vertices, I instead store an array of Scalars, adding 3 scalars per point. I pass this array to the constructor directly.

Code: Select all

mCollisionShape = new OgreBulletCollisions::ConvexHullCollisionShape(pointsArray,
                                                                     mPoints->size(),
                                                                     sizeof(btVector3));
This is a bit faster but still above 5,000 ms on average.


Note: I am using OgreBullet's ConvexHullCollisionShape which is simply a very thin wrapper over btConvexShape, here's the constructor:

Code: Select all

ConvexHullCollisionShape::ConvexHullCollisionShape(const Real* points, int numPoints, int stride)
        : CollisionShape() {
    mShape = new btConvexHullShape((btScalar*) points, numPoints, stride);
}
I'm assuming this isn't a problem with OgreBullet.
RedToasty
Posts: 7
Joined: Wed Jan 18, 2012 9:54 am

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by RedToasty »

I'm using a btCompoundShape for each nearby chunk, when I spin through to calculate visible faces I add all the external boxes with addChildShape. It's very fast, my main issue at the moment is the amount of memory and allocations used, I'm writing for mobile phone so it's pretty limited.

I really want to have a stab at setting up a custom shape that looks directly into the block data, each of my btBoxShapes has it's own transform so takes up about twice as much space as it needs.
RedToasty
Posts: 7
Joined: Wed Jan 18, 2012 9:54 am

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by RedToasty »

Quick update, I was using quite an old version of Bullet. Updating to the latest totally fixed my spiking frame rate, I was still getting about 100,000 allocations which killed my memory tracking. I then noticed you can stop btCompoundShapes building internal AABB trees, pop went all the allocations.

Running very well now with 8x4x8 chunks active, 32x16x32 blocks in each chunk (which is purely for a rendering limitation on my end), on Android devices. Dropping 20 big boxes on the terrain and letting them roll around barely gets it up to 2ms update.
Razorstorm
Posts: 4
Joined: Sat Feb 23, 2013 9:30 pm

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by Razorstorm »

Ah so this looks promising, I'll look into using compoundshapes of boxshapes.

How did you stop it from building internal AABB trees? Also, did this impact broadphase/narrowphase and/or raytracing performance?
RedToasty
Posts: 7
Joined: Wed Jan 18, 2012 9:54 am

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by RedToasty »

Since I'm using a btCompoundShape per chunk, the boxes are very close together anyway. I don't think it massively benefits from being octree'd up internally, if anything I seem to be getting better performance with it disabled. That said, my terrain is a fairly simple perlin noise height map at the moment, it'll be more interesting to test with some caves dug into it.

Just pass btCompoundShape(false) when you construct it and the AABB generation will be disabled. Since you're working within Ogre you might find it's better enabled anyway to be honest. Another bonus of not using AABBs should be I'd imagine it's quicker for adding/removing child objects.

The broadphase uses the AABB of the entire compound shape, which will still work fine, this just disabled AABBs on internal objects.

I'd planned to have a stab at writing a custom shape tonight, but to be honest I think it'll do like this for the moment :)
Razorstorm
Posts: 4
Joined: Sat Feb 23, 2013 9:30 pm

Re: Constructing a btBvhTriangleMeshShape is very slow

Post by Razorstorm »

Cool, your use case seems very similar to mine at the moment, so I'm sure this should work for me too.

My terrain is also a simple perlin noise with chunk sizes of 32x32x32 blocks per chunk (obviously I can tweak this for performance).

I just implemented compound shapes for collision and everything seems to be going pretty well. I still have some random runtime errors, but I think those are due to mistakes on my part.

Thanks for the help!