The number of vertices in the final ConvexHullShape- where you measured 271, 219, 146, 89, 108- is the relevant metric for convex hull performance. For a real time game-like application, I would recommend those numbers being closer to 6-30.
However, a full second for collision detection is very high, even taking into account the high vertex count.
For reference, I set up a quick demo in the BEPUphysics demos to test. I created 30 ballish convex hulls all near each other, each with 250 surface vertices. The result is 435 collision pairs with mostly deep contacts. After disabling the solver for the involved pairs, the single threaded time is ~49ms on my 3770K@4.5ghz. The E5620 is about half as fast in terms of single threaded performance, so I'd expect the same simulation to take ~100ms on it. Here's the simulation if you want to try it out:
Code: Select all
var points = new List<Vector3>();
Space.ForceUpdater.Gravity = new Vector3();
var random = new Random(0);
for (int shapeIndex = 0; shapeIndex < 30; ++shapeIndex)
{
var center = new Vector3(2 * (float) random.NextDouble(), 2 * (float) random.NextDouble(), 2 * (float) random.NextDouble());
for (int k = 0; k < 250; k++)
{
var direction = Vector3.Normalize(new Vector3(-1 + 2 * (float)random.NextDouble(), -1 + 2 * (float)random.NextDouble(), -1 + 2 * (float)random.NextDouble()));
points.Add(center + direction);
}
var convexHull = new ConvexHull(points, 10);
convexHull.CollisionInformation.CollisionRules.Personal = BEPUphysics.CollisionRuleManagement.CollisionRule.NoSolver;
convexHull.ActivityInformation.IsAlwaysActive = true;
Console.WriteLine("Convex hull point count: " + convexHull.CollisionInformation.Shape.Vertices.Count);
Space.Add(convexHull);
}
So even assuming your simulation is single threaded and has as many overlaps as this (which would basically require both robots being compressed together into a tiny box), there's still a factor of 10 performance difference to figure out.
Are you using the Space.Update(dt) overload where dt is the time since the previous frame? Using that overload will make the engine take multiple timesteps in an attempt to catch up with the accumulated time. It gives up after Space.TimeStepSettings.MaximumTimeStepsPerFrame, which defaults to 3. So, if the simulation is complicated enough to take longer than a frame's duration consistently, it could end up entering a vicious cycle where it just can't keep up. In that case, just using one time step per frame via Space.Update() with no parameter could help responsiveness by just letting the simulation run slower than real time.
But even that alone doesn't explain the full performance difference. How complicated are the MobileMeshes? A mesh with a thousand triangles deeply intersecting another mesh would hurt pretty bad. It would be roughly as expensive as a thousand simple primitives being queried against a static mesh. It gets even worse if the MobileMesh has interior solidity enabled. For any nontrivial mesh, I would strongly recommend decomposing the mesh into multiple convex hulls instead. There exist some handy automated tools that can do a good job of this, like
V-HACD. Combined with some form of mesh simplification prepass, 100x faster collision detection is very possible.
It would probably be a good idea to run some form of profiler to get a better idea about what systems are actually taking up the time before jumping into anything work intensive.