[SOLVED] Convex Shape Confusion

Post Reply
pp57
Posts: 5
Joined: Tue Oct 18, 2016 11:41 am

[SOLVED] Convex Shape Confusion

Post by pp57 »

Hi all,

I've been playing around with Bullet for a bit now but I've mainly used basic shapes for collision detection. I'm now looking at using generic triangular meshes but I'm a bit confused - I've got the convex triangular collision shapes with btConvexTriangleMeshShape working but when I run the convex hull creation algorithm over it to simplify the mesh further, I get quite bizarre results, see below for a basic box mesh (shows the mesh from debugDrawWorld() with DBG_DrawWireframe set):

Image

Here's what I'm doing in code:

Code: Select all

std::unique_ptr<btConvexShape> intermediateShape = std::make_unique<btConvexTriangleMeshShape>(triMesh.get()); // triMesh is a btTriangleMesh with all the vertices
std::unique_ptr<btShapeHull> hull = std::make_unique<btShapeHull>(intermediateShape.get());
hull->buildHull(intermediateShape->getMargin());
collisionShape_ = std::make_unique<btConvexHullShape>(reinterpret_cast<const float*>(hull->getVertexPointer()), hull->numVertices()); // collisionShape_ is the main shape for the rigid body in question
I've also tried adding the vertices from the hull shape one-by-one to the collisionShape_ but no avail. Any ideas/help would greatly be appreciated!

Thanks!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Convex Shape Confusion

Post by drleviathan »

My guess is that the convex-hull generation code is using the collision margin of the original shape.

To understand collision margins in Bullet you can watch this youtube video.

Now imagine what the convex hull of a cube with collision margin would look like. Maybe you should shrink the margin to zero before passing it to the algorithm?

BTW, when generating the convex-hull I recall that it is possible to specify the max number of points of the result. You could try specifying that the convex-hull result not have more points than the original convex-triangle-mesh -- you'll tend to recover the original shape better. I think the convex-hull generation method uses no more than 42 vertices -- that correspond to the 42 distinct directions of the supporting vertex implementation of the btConvexHullShape.

Why 42? Probably because the regular icosahedron has 12 vertices and 30 edges: if you trace outward from the vertices and the midpoints of the edges it provides 42 relatively equally spaced directions distributed on the unit sphere. Alternatively you can think of them as the vertices of a 2nd frequency geodesic sphere.
pp57
Posts: 5
Joined: Tue Oct 18, 2016 11:41 am

Re: Convex Shape Confusion

Post by pp57 »

drleviathan wrote:My guess is that the convex-hull generation code is using the collision margin of the original shape.

To understand collision margins in Bullet you can watch this youtube video.

Now imagine what the convex hull of a cube with collision margin would look like. Maybe you should shrink the margin to zero before passing it to the algorithm?

BTW, when generating the convex-hull I recall that it is possible to specify the max number of points of the result. You could try specifying that the convex-hull result not have more points than the original convex-triangle-mesh -- you'll tend to recover the original shape better. I think the convex-hull generation method uses no more than 42 vertices -- that correspond to the 42 distinct directions of the supporting vertex implementation of the btConvexHullShape.

Why 42? Probably because the regular icosahedron has 12 vertices and 30 edges: if you trace outward from the vertices and the midpoints of the edges it provides 42 relatively equally spaced directions distributed on the unit sphere. Alternatively you can think of them as the vertices of a 2nd frequency geodesic sphere.
Thanks for the quick reply - that video was also incredibly useful! You were right about the margins - when I set them to zero before passing them to the hull generation function, I retrieved a mesh with just the expected 8 vertices. The only thing is that the mesh doesn't make sense when rendered with the debugger:

Image

Does Bullet actually generate a triangular surface for the hull or is the debugger just connecting up the 8 vertices somehow?

Thanks again!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Convex Shape Confusion

Post by drleviathan »

The btShapeHull::buildHull() operation does generate a triangular mesh, but the btConvexHullShape itself only keeps the vertices and discards the connectivity data. It does look as if the graphical representation is just a list of the 8 points, but I don't have much experience using the visual debugger stuff.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Convex Shape Confusion

Post by Erwin Coumans »

By default, Bullet doesn't create or use triangle information in the convex hull computations (GJK, EPA, MPR etc). Those algorithms only use vertices to compute the 'support' vertex. Since there are no triangles/edges, the debug rendering looks very ugly, as you noticed.

You can create polyhedral features using the "btConvexHullShape::initializePolyhedralFeatures" method. That will make the debug rendering more pretty, but doesn't change anything related to collision detection etc.

It is recommended to the 'btConvexHullShape::optimizeConvexHull' method first, which removes internal vertices etc.

Finally, if you really want, you can also enable the separating axis test (SAT) based collision detection. If enabled AND you generated polyhedral features, it will be used instead of GJK/EPA. To enable this, use world->getDispatchInfo().m_enableSatConvex=true;
pp57
Posts: 5
Joined: Tue Oct 18, 2016 11:41 am

Re: Convex Shape Confusion

Post by pp57 »

Call to initializePolyhedralFeatures did the trick and I can now see a proper cube:

Image

Thanks drleviathan and Erwin!
Post Reply