Dynamic collisions of possibly concave objects (please help)

Post Reply
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Dynamic collisions of possibly concave objects (please help)

Post by mrbob »

Total newb of bullet(sharp) here. Taking over an existing project which uses bulletsharp and discovered that collisions are totally broken.

I have around 20 or 30 possibly concave mesh which need to highlight when they are colliding with each other (objects are movable by mouse select & drag).
Currently the collidables for the mesh are BvhTriangleMeshShape's. This I discovered is probably the reason for why collisions are not registering.

I altered the code to use GImpactMeshShape with the existing TriangleIndexVertexArray data and added world.RegisterAlgorithm(dispatcher);

This works but is incredibly slow. PerformDiscreteCollisionDetection(); takes close to a minute to complete.
Note: I'm not sure if this is related but I don't see code anywhere which adds the objects as rigid bodies to the world. Not sure if this needs to be done actually.

I'm not sure what else I can try here... (maybe convex decomposition?). :(
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Re: Dynamic collisions of possibly concave objects (please h

Post by mrbob »

Convex decomposition might work but the problem is that it is also far too slow for our meshes as well.
I'm inclined to believe that I might have to find another library to do collision detection.
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: Dynamic collisions of possibly concave objects (please h

Post by hyyou »

How many vertex per body?
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Re: Dynamic collisions of possibly concave objects (please h

Post by mrbob »

Around 6000 vertices per body with between 10-20 bodies.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Dynamic collisions of possibly concave objects (please h

Post by drleviathan »

The "algorithm" for colliding two btBvhTriangleMeshShape has not been implemented, which is why RigidBody's that use that shape can only be STATIC not DYNAMIC or KINEMATIC.

Yes, convexification works well. You pre-compute the convex parts using some modelling software (Maya, Blender) or with a library like V-HACD (an older version is distributed with the Bullet codebase) and assemble them in a btCompoundShape with appropriate local transforms.

If Bullet is running slow for your simulation then you are probably doing something wrong. It should handle 20-30 objects just fine. What exactly is going wrong is not clear but I speculate:

(1) The objects are too complicated. Count the triangles of your meshes and consider whether there are more than necessary for the fidelity of the collision tests you need.

(2) You may be using an old version of Bullet. I don't know the status of the efficiency of sweep tests against btBvhTriangleMeshShape in Bullet 2.83 but sweeps against btCompoundShape are definitely slow there. That is fixed, along with several other things, at the tip of the Bullet codebase.

(3) You have not optimized. By default Bullet constantly updates the Aabb of all static objects static every simulation step. You can disable that but then you must manually update the Aabb whenever you move one.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Dynamic collisions of possibly concave objects (please h

Post by drleviathan »

Also, there is an easy way to capture the timings of the Bullet physics simulation step using the CProfileManager (look for an example in the code). The results can be printed to std::out and are easy to understand.
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Re: Dynamic collisions of possibly concave objects (please h

Post by mrbob »

Thanks for the suggestions, I will look at the CProfileManager. But to be honest the code is so simple that I would be surprised, but maybe there is something obvious that I overlooked.
I am currently using the latest version of BulletSharp PInvoke: https://github.com/AndresTraks/BulletSharpPInvoke
Pre-computing the HACD isn't really an option for this project so unless it is possible to do this during run time efficiently I will need to focus on other approaches.

Code: Select all

[TestMethod]
        public void ComplexCollisionsTest()
        {
            var bt_collision_configuration = new DefaultCollisionConfiguration();
            var bt_dispatcher = new CollisionDispatcher(bt_collision_configuration);

            //This is one type of broadphase, bullet has others that might be faster depending on the application
            BroadphaseInterface bt_broadphase = new DbvtBroadphase();

            var bt_collision_world = new CollisionWorld(bt_dispatcher, bt_broadphase, bt_collision_configuration);
            
            var mesh = /* load mesh */
            StridingMeshInterface arrays = new TriangleIndexVertexArray(mesh.Triangles, mesh.Vertices);

            //Create a sphere with a radius of 1
            var sphere_shape = new GImpactMeshShape(arrays);
            sphere_shape.UpdateBound();

            GImpactCollisionAlgorithm.RegisterAlgorithm(bt_dispatcher);

            var list = new List<CollisionObject>();

            for (int i = 0; i < 8; i++)
            {
                //Create two collision objects
                var sphere_a = new CollisionObject();
                list.Add(sphere_a);
                sphere_a.CollisionFlags = CollisionFlags.NoContactResponse | CollisionFlags.KinematicObject |
                                          CollisionFlags.DisableVisualizeObject;
                //Move each to a specific location
                sphere_a.WorldTransform = Matrix.Translation(10, 10, 10);

                //Set the shape of each collision object
                sphere_a.CollisionShape = sphere_shape;
                sphere_a.CollisionShape.Margin = 0.1f;
                //Add the collision objects to our collision world
                bt_collision_world.AddCollisionObject(sphere_a);
            }

            //Perform collision detection
            bt_collision_world.ForceUpdateAllAabbs = false;
            Stopwatch watch = new Stopwatch();
            watch.Start();
           /////////////////////////////
            // SLOW HERE!!!!
            bt_collision_world.PerformDiscreteCollisionDetection();
            watch.Stop();
            Debug.WriteLine(watch.Elapsed);

            var num_manifolds = bt_collision_world.Dispatcher.NumManifolds;

            num_manifolds.ShouldBeEquivalentTo(1);

            for (var i = 0; i < num_manifolds; i++)
            {
                var contact_manifold = bt_collision_world.Dispatcher.GetManifoldByIndexInternal(i);
                var ob_a = contact_manifold.Body0;
                var ob_b = contact_manifold.Body1;

                contact_manifold.RefreshContactPoints(ob_a.WorldTransform, ob_b.WorldTransform);

                var num_contacts = contact_manifold.NumContacts;

                //For each contact point in that manifold
                for (var j = 0; j < num_contacts; j++)
                {
                    //Get the contact information
                    var pt = contact_manifold.GetContactPoint(j);
                    var pt_a = pt.PositionWorldOnA;
                    var pt_b = pt.PositionWorldOnB;
                    double ptdist = pt.Distance;
                }
            }

            bt_collision_world.Dispose();
        }
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Dynamic collisions of possibly concave objects (please h

Post by drleviathan »

Yes that is simple enough. I see that you've already disabled the automatic Aabb update that I mentioned in item (3) above

The good news is that btCollisionWorld::performDiscreteCollisionDetection() and its sub-calls are indeed instrumented with CProfileManager timing.

The bad news is that it probably has something to do with the mesh you are loading. If you have to test really complex shapes then you might just be out of luck when it comes to running collision tests in real time.

In the example above you're using GImpactShape rather than btBvhTriangleMeshShape. I suppose you could try it for implicit spheres just to verify that Bullet actually works fast in the simplest case and if that looks good you could make some experimental sub-shape-heavy btCompoundShape and try colliding those to see how performance changes. These tests would probe the source of the slowness without resorting to CProfileManager.

It is probably not possible for you to do convex decomposition (e.g. V-HACD) in real-time. It can take anywhere from a large fraction of a second to several hundreds of seconds to compute the convex decomposition of a complex mesh, depending on: the version of V-HACD you're using, the parameters you pass it, and whether you're running on CPU or GPU. I don't know BulletSharp so I can't say whether it has exposed V-HACD anyway.
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Re: Dynamic collisions of possibly concave objects (please h

Post by mrbob »

CProfileManager doesn't appear to be available in BulletSharp :(

I'm using GImpactMeshShape because btBvhTriangleMeshShape will not register collisions with other btBvhTriangleMeshShapes.

I also tried it with spheres and it works as fast as you would expect, so it does appear to be related to the mesh I am using. But I wouldn't consider these mesh to be complex at all so I'm pretty surprised to get such abysmal results :(
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: Dynamic collisions of possibly concave objects (please h

Post by hyyou »

6000 vertices x 10-20 bodies
I have tested : 4000 dynamic cubes can reach the system limit of Bullet for a simple game.
According to official guide, triangle meshes management is poorly optimized relative to cube.
Thus your situation may reach the threshold.

Higher amount of bodies & lower amount of vertex per body might help. (AABB may be culled better.)
I am not sure.
mrbob
Posts: 7
Joined: Mon Sep 19, 2016 4:17 pm

Re: Dynamic collisions of possibly concave objects (please h

Post by mrbob »

Thanks for the feedback. So the conclusion basically is that GImpactMesh is just not optimized to deal with complex mesh.

I have been testing GhostObject and also just doing ContactPairTest's on objects and this appears to be a lot faster. Maybe I can make it work with this approach.
Post Reply