[ODE] A question on contacts and their persistence

Shamyl Zakariya shamyl at zakariya.net
Tue Jan 16 12:03:36 MST 2007

I've just written a quick test which visualizes contacts generated in  
my nearCallback function. I'm interested in making it easy for  
Entities in my app to be able to "know" what other Entities they're  
touching, as well as being able to grab an array of all contacts  
between all Entities in the World. This data is updated with each  

That being said, to all appearances my quick demo -- which is just  
dropping capsules on a box -- works correctly. Collisions work, stuff  
bounces and rolls as to be expected. So I'm not complaining about bad  
behavior. The trouble is the visualization of the contacts generated.

My understanding is that ODE may generate more than one contact  
between two touching geoms. When, say, a capsule is touching a box  
there ought to be a minimum of two contact points. But what I'm  
seeing is one contact jumping back and forth ( flickering, actually,  
so fast that both contact points appear transparent ). I've taken a  
few screenshots so you can see the contact points bouncing about:


What I want to know is whether this is actually how ODE works --  
e.g., one contact point at a time for each two touching bodies, but  
this point bounces around with each call to dSpaceCollide. Or,  
perhaps I'm incorrectly gathering the contact information.

Below is my nearCallback. The middle is snipped, all that matters is  
the last bit.

void nearCallback( void *data, dGeomID g1, dGeomID g2)
     World *world = (World *) data;

     EntityRef e1 = Entity::entityForGeom( g1 ),
               e2 = Entity::entityForGeom( g2 );

     if ( e1 && e2 )
         if ( !e1->allowCollisionWith( e2 ) || !e2->allowCollisionWith 
( e1 )) return;


     const int maxContacts = 24;
     dContact contacts[maxContacts];
     for (int i = 0; i < maxContacts; i++)
         contacts[i].surface.mode = dContactSoftCFM | dContactSoftERP;
         contacts[i].surface.mu = combinedMu;
         contacts[i].surface.soft_cfm = 0.0001f;
         contacts[i].surface.soft_erp = 0.2f;

     if ( int numc = dCollide( g1, g2, maxContacts, &contacts 
[0].geom, sizeof(dContact)) )
         for ( int i = 0; i < numc; i++ )
             dJointID c = dJointCreateContact( world->_world, world- 
 >_contactGroup, &(contacts[i]) );
             dJointAttach( c, b1, b2 );

             // make a Contact from the two Entities
             Contact ct( e1, e2, contacts[i].geom.pos, contacts 
[i].geom.depth );

             if ( e1 )
                 e1->addContact( ct );
                 e1->collision( e2, contacts[i].geom.pos, contacts 
[i].geom.normal, contacts[i].geom.depth );

             if ( e2 )
                 e2->addContact( ct );
                 e2->collision( e1, contacts[i].geom.pos, contacts 
[i].geom.normal, contacts[i].geom.depth );

             // add to World's contacts vector
             world->_contacts.push_back( ct );


shamyl at zakariya.net
	In the same episode, the scientist suggests that the
	debigulation can only be reversed by a rebigulator.
		-- wikipedia

More information about the ODE mailing list