btCollisionWorld::convexSweepTest Performance Implications On Switch

Post Reply
Kaiser
Posts: 1
Joined: Sat Aug 13, 2022 6:24 pm

btCollisionWorld::convexSweepTest Performance Implications On Switch

Post by Kaiser »

I am implementing a collision system involving moving an object composed of a cylinder through the world via btCollisionWorld::convexSweepTest to perform slide movement. The code setup is very similar to that of player slide physics code as seen in https://github.com/RobertBeckebans/RBDO ... r.cpp#L175 in which the slide movement routine may go through several iterations (up to 5) until the direction of movement is parallel with all the collision planes as well as several additional tests for checking stairs, ramps, etc.

I've noticed that the most trivial usage of convexSweepTest on the Nintendo Switch would take up to ~0.5ms to even 1.5ms for just the player alone. There are expectations that there will be multiple objects that will also need to perform slide movement, so performance is already becoming a huge concern. I even found performance to take a significant drop when colliding against creases and other corners. Upon profiling, I saw that the majority of the CPU time spent in was in btGjkPairDetector::getClosestPointsNonVirtual.

The level is composed roughly of ~220 collision objects, which consists of chunks of the level with different filter settings, all using btBvhTriangleMeshShape for the shape type. For moving the object, I use a btCylinderShapeZ for the shape and then calling convexSweepTest to move the object. I also use a custom class that inherits btCollisionWorld::ClosestConvexResultCallback to perform custom filtering as some surfaces are flagged to allow certain objects to collide / don't collide with, such as climbable surfaces, water, shoot-through, etc.

So I am trying to understand *why* its so expensive, even from doing a simple movement from point A to point B. Is it because there are too many static collision objects? I also have setForceUpdateAllAabbs enabled, which otherwise performance would be even worse than what it is right now. Also note that I am testing on a shipping/non-debug build with all optimizations enabled.

I appreciate anyone's time.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: btCollisionWorld::convexSweepTest Performance Implications On Switch

Post by drleviathan »

I too have seen high CPU costs when sweeping against btBvhTriangleMeshShape. This is what I remember:

(1) Make sure your mesh is actually using a Boundary Volume Hierarchy. The current version of the btBvhTriangleMeshShape ctor I'm seeing looks like this:

Code: Select all

btBvhTriangleMeshShape(btStridingMeshInterface * meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
However, older versions (from five or six years ago?) had the default buildBvh=false, so check your header.

(2) btBvhTriangleMeshShape works well when the triangles are bigger than the things colliding against it. In other words: if you use a btBvhTriangleMeshShape for a big terrain with little slow cylinders moving along it then great! but if you use btBvhTriangleMeshShape for a house and then throw a big fast truck at it that is nearly as big as the house itself... then you're in for a very expensive collision because the overlap will query nearly every triangle.

(3) Prefer triangles with approximately equal sides in your mesh. Long thin triangles that span the mesh tend to make for poor BVH structure. I suspect drastic triangle size variations also make the BVH suffer, but I haven't investigated this: e.g. a mesh with a mix of very large triangles and very tiny.

Edit: I forgot to mention: in my case I decided to NOT perform sweep tests against the meshes because it was just too expensive and I couldn't control the complexity/quality of the meshes (user generated content). I settled on a dynamic character that performed many short ray-traces instead of sweeps.
Post Reply