[ODE] Performance patch : not checking collision between disabled bodies

Joe Ante joe at uti.is
Wed May 26 13:34:15 MST 2004


Hi Nguyen,

I think this optimization should be handled at a different level.

CollideAABBs happens after broad-phase culling, so essentially if you have
large scenes with a lot of static geometry and lot of sleeping bodies, you
will still waste a lot of time in the broad phase culling.

In my opinion a better solution is to use two spaces.
A disabled space and and enabled space.

When objects begin sleeping they are moved to the disabled space.
When objects awake they are moved into the enabled space.

Then you collide the enabledspace with itself.
And the enabledspace with the disabled space.
But you don¹t collide any disabled objects with each other.

For a typical game like situation eg. First person shooters lots of static
geometry and lots of sleeping bodies and few moving rigid bodies is normal.

Thus broad phase culling can become a major factor and it has been in one of
the projects I have worked on with ode.

I have implemented the enable / disable callback functions in ode.
In the disable / enable callbacks I add remove the geoms from
enabled/disabled space.

Once that is working the performance optimization you propose will not be
necessary anymore thus I think it could just as well be left out. (Aside
from that you can do the same test inside near callback if you want to.)

Joe Ante
www.otee.dk

> Hi Russ,
> 
>  Another performance patch.
> 
>  The situation is:
>  Now, ODE checks collision between all objects in the scene even
>  between two disabled bodies.
> 
>  Here is a small patch for the case :
>  search in collision_space_internal.h
> 
> static void collideAABBs (dxGeom *g1, dxGeom *g2,
>                         void *data, dNearCallback *callback)
> {
> dIASSERT((g1->gflags & GEOM_AABB_BAD)==0);
> dIASSERT((g2->gflags & GEOM_AABB_BAD)==0);
> 
> // no contacts if both geoms on the same body, and the body is not 0
> if (g1->body == g2->body && g1->body) return;
> 
> // Add those lines
> // no collision between geom of disable body
> if (g1->body == 0) // g2->body must be != 0 and must not be disable
> {
>         if ((g2->body->flags & dxBodyDisabled)!=0)
>         {
>                 return;
>         }
> }
> else if (g2->body == 0) // g2->body must be != 0 and must not be disable
> {
>         if ((g1->body->flags & dxBodyDisabled)!=0)
>         {
>                 return;
>         }
> }
> else
> {
>         // two bodies are valid
>         if (((g2->body->flags & dxBodyDisabled)!=0)
>                 && ((g1->body->flags & dxBodyDisabled)!=0))
>         {
>                 // two bodies are disable so don't bother collide them
>                 return;
>         }
> }
> // End add code
> 
> // test if the category and collide bitfields match
> if ( ((g1->category_bits & g2->collide_bits) ||
>       (g2->category_bits & g1->collide_bits)) == 0) {
>   return;
> }   
> 
> This patch comes with new auto-disable method will boost ODE
> performance in many real life cases.




More information about the ODE mailing list