Contact Pairs

Just tried to use the contact pair concept for colliding several objects and does not seem quite sound: Do I have to register the contact pair for 100 objects that can collide with each other for each possible pair?! This would mean to register it 4950 times (100!/(98!*2!)) 8-O

Addionally when I do

world.addContactPair( a, b, pair1 )
world.addContactPair( b, c, pair2 )
world.addContactPair( a, c, pair2 )


pair1 is not regarded any more!

Have I misunderstood something very badly? Or is the ContactPair solution simply impractical?

I have written a unit test to check the behaviour described above:

package jmextest.physics;

import junit.framework.TestCase;
import com.jme.scene.Node;
import com.jmex.physics.*;
import com.jmex.physics.contact.ContactPair;
import com.jmex.physics.types.PhysicsSphere;
import org.odejava.collision.Contact;

/**
 * @author irrisor
 * @created 09.04.2005, 13:16:49
 */
public class ContactTest extends TestCase
{
   public void testContactPairAssignment()
   {
      PhysicsWorld.create();

      final Node sphere1Node = new Node("sphere1");
      final DynamicPhysicsObject sphere1 = new DynamicPhysicsObject( sphere1Node, new PhysicsSphere( 1 ), 1 );
      final PhysicsWorld physicsWorld = PhysicsWorld.getInstance();
      physicsWorld.addObject( sphere1 );

      final Node sphere2Node = new Node("sphere2");
      final DynamicPhysicsObject sphere2 = new DynamicPhysicsObject( sphere2Node, new PhysicsSphere( 1 ), 1 );
      physicsWorld.addObject( sphere2 );

      final Node sphere3Node = new Node("sphere3");
      final DynamicPhysicsObject sphere3 = new DynamicPhysicsObject( sphere3Node, new PhysicsSphere( 1 ), 1 );
      physicsWorld.addObject( sphere3 );

      final boolean[] pairsAsked = new boolean[3];

      final ContactPair contactPair_1_2 = new ContactPair()
            {
               public void onContact( PhysicsObject object1, PhysicsObject obj2, Contact contact )
               {
                  System.out.println( "1 & 2 processed" );
                  pairsAsked[0] = true;
               }
            };
      physicsWorld.addContactPair( sphere1, sphere2, contactPair_1_2 );

      final ContactPair contactPair_1_3 = new ContactPair()
      {
         public void onContact( PhysicsObject object1, PhysicsObject obj2, Contact contact )
         {
            System.out.println( "1 & 3 processed" );
            pairsAsked[1] = true;
         }
      };
      physicsWorld.addContactPair( sphere1, sphere3, contactPair_1_3 );

      final ContactPair contactPair_2_3 = new ContactPair()
      {
         public void onContact( PhysicsObject object1, PhysicsObject obj2, Contact contact )
         {
            System.out.println( "2 & 3 processed" );
            pairsAsked[2] = true;
         }
      };
      physicsWorld.addContactPair( sphere2, sphere3, contactPair_2_3 );

      physicsWorld.update( 1 );

      assertTrue( "1 & 2 collision not processed correctly", pairsAsked[0] );
      assertTrue( "1 & 3 collision not processed correctly", pairsAsked[1] );
      assertTrue( "2 & 3 collision not processed correctly", pairsAsked[2] );
   }
}


But it seems to me that it's not very useful to repair the contact pair any more...

ContactPairs are meant to define how the physics engine handles a collision between two objects. You are not meant to have 100 of them lying around…



Basically, with us using ODE, there is no other alternative. Contact Points are generated when a Geom collides with another. Those contactPoints need to have a way to know what slip, friction, bounce…etc to apply in each direction. There is a default contactPair, which will work for any colliding objects.



In the usual ode way, you would nest a LOT of if/else statements to check whether this and that object have collided, if so, set this contact, else if A and B have collided, that contact, R and T collided, that contact. We’re doing the same, but in a more OO way. When R and T collide, we call their ContactPair that has been assigned to them…



To be honest, i dont like it either, but we’re stuck with it. I tried to make “materials” whereby each physics object is wrapped in a material, and the contact is the average slip of the two materials, or the average friction…but that didn’t turn out too well as you could never predict the outcome of the collision reliably. Maybe you would like something like that? Im sure we can make something work reliably…



Btw, i’l fix that contactPair bug, or do you want us to work on a materials system?



DP

Hmm, maybe I did not explain it very well, I don’t need 100 contact pair objects, but: I have 100 objects moving around and they should have a special contact behaviour with each other.

What would the code be for that?

The naive way would be something like:

  ContactPair theContactPair = new MyContactPairImpl();
  for ( i=0; i<objectcount; i++ )
    for ( j=0; j<objectcount; j++ )
       world.addContactPair( objects[i], objects[j], theContactPair );


Resulting even in 10000 calls to addContactPair.
With the current implementation one can do this:

  ContactPair theContactPair = new MyContactPairImpl();
  for ( i=0; i<objectcount-1; i++ )
       world.addContactPair( objects[i], objects[i+1], theContactPair );


But it's not possible to define the collision behaviour with more than one object type at this time (as shown in the above post).

Materials would not help me, as some of my objects (space ship energy shields) reflect on one side and let other objects pass through on the other...

I think the only practical way is the usual ode way :(

I agree its a current bug with not defining more than 1 contact pair for an object…i should get that fixed ASAP so you can do your thing.



Materials would not help me, as some of my objects (space ship energy shields) reflect on one side and let other objects pass through on the other...


In that case, i suggest you have two objects instead of one there...one for letting stuff go through, the other for reflecting. This way, you can add more than one material onto each object and cancel the contact if you want.

Btw, im starting to push for this material thing as I think it makes perfect sense. You define the type of material the object has, i.e. how much friction, slip, motion, whether its penetrable or not...etc and add it the physics object. When two objects collide with different materials, the average is taken by the two materials.

Think about it like this, your a car, going on solid nicely paved road, you have certain friction that drives teh car forward in a nice manner, all of a sudden you hit a dirt track, now your slip is more, your friction is more...i.e. rally car.

The only thing im not so sure about is this average thing, but im sure we can work something out there...

DP
"DarkProphet" wrote:
In that case, i suggest you have two objects instead of one there...one for letting stuff go through, the other for reflecting.
??? I don't think that this would be possible. At this time I use it do have dynamic objects that are only a part of a sphere. It will certainly work when one could use a trimesh as dynamic object but they don't work very well in ode (collision is not detected very often).
"DarkProphet" wrote:
Btw, im starting to push for this material thing as I think it makes perfect sense. [...] The only thing im not so sure about is this average thing, but im sure we can work something out there...
One cannot easily work out something that matches reality: E.g. take two dry pieces of soap and rub them against each other -> hight friction; take two pices of silicon -> very high friction; finally take a piece of soap and a piece of silicon -> very low friction...
That's why ode has no materials... but this should not stop you from providing a simpler solution. Simply allow custom handling, too.
(As I want to do my energy shields with it :D )

I would propose something like the ContactAction concept (with another name than 'action', e.g. ContactHandler) and provide a MaterialContactHandler by default that regards Materials but might be replaced by a handler containing user code.