x


Colliders slow for crowds?

I have 800 boids with SphereColliders on them. I use them to determine neighbor boids for each bird. At the beginning when the boids are close to each other I get lots of collisions and my frame rate drops to 5fps. But when they spread my frame rate jumps to 20fps.

Why the speed difference is so high? Is there some internal Unity/PhysX messaging that is so expensive? I don't do anything on OnTriggerEnter (yet) but obviously physics engine has to check for collisions between all the colliders every frame because I make them kinematic and animate them by myself.

more ▼

asked Jul 06 '10 at 09:46 AM

vorg gravatar image

vorg
36 1 1 5

You don't really need colliders to do the boids algorithm, the only thing I can suggest is to lower the radius of the spheres or make them solid so that there's no overlap of several colliders

Jul 06 '10 at 09:50 AM spinaljack

Performance can depend on a host of things, including how you're detecting proximity. It would probably behoove you to first ensure that the physics are actually what's slowing you down.

Jul 06 '10 at 11:17 AM Ricardo
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

The physics engine can accelerate the check whether objects do collide by checking whether the bounding boxes collide. This is very fast. Example of what the engine is probably doing:

BAD implementation would be:

// Checking for sphere collisions
if((a.position - b.position).magnitude < (a.radius + b.radius))
{
  // the spheres collide
}

GOOD implementation would be:

var dist = a.radius + b.radius;
// first checking for bounding box collisions
if
(
  (Mathf.Abs(a.position.x - b.position.x) < dist) &&
  (Mathf.Abs(a.position.y - b.position.y) < dist) &&
  (Mathf.Abs(a.position.z - b.position.z) < dist) &&
  ((a.position - b.position).magnitude < (a.radius + b.radius))
)
{
  // there spheres collide
}

The second thing is incredibly faster, because it will stop checking when the first condition evaluates to "false" and only do the (slower) full check if all the other conditions meet. For example: A is far left from B, so there is no need to calculate the distance of them - you already know they don't collide.

But if all objects are close to each other, the full test has to be made, and this will really slow down - you notice it by the frame rate drop.

more ▼

answered Jul 06 '10 at 01:04 PM

felix. gravatar image

felix.
1.9k 18 23 47

I also remembered the term for it: short-circuit evaluation, http://en.wikipedia.org/wiki/Short-circuit_evaluation.

Jul 06 '10 at 01:15 PM felix.

even faster - use sqrMagnitude, and check it's less than Mathf.Pow(a.radius + b.radius, 2)

Jul 06 '10 at 01:24 PM Mike 3

While it is generically true that bounding box evaluations are used to speed up collision detection, in the case of two spheres, the test itself (using sqrMagnitude as Mike wrote) is probably actually faster then a bounding volume test, because it has to do less branches.

Jul 06 '10 at 03:12 PM jonas echterhoff ♦♦

No, its not the actual sphere collision equation (which can be surely made faster) thats faster, its the short-circuit evaluation. "Nearly all" (as a mathematician would probably say) collision tests are finished after |a.x - b.x| < dist.

Jul 06 '10 at 06:29 PM felix.

OK, then, can I disable full testing somehow? Just the first test would be enough for me.

Jul 08 '10 at 08:38 AM vorg
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1877
x472

asked: Jul 06 '10 at 09:46 AM

Seen: 1265 times

Last Updated: Jul 06 '10 at 09:46 AM