[ODE] Collision callback pattern
Dave Lloyd
dave at chaos.org.uk
Mon Sep 1 09:09:07 2003
This is a multi-part message in MIME format.
--------------040204000909040800050303
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Greetings all,
I've been playing with ODE for a little bit now and have a set of Java
bindings that I will shortly be releasing. I'm currently trying to tidy
up the collision callback which is a bit clumsy through Java. The most
awkward bit (more so than it first seemed) is in providing a contact
array - as things stand I can only easily provide *one* contact which is
not sufficient. Anything more and I run into scope violations or storage
freeing problems. So I've been thinking about refining the callback
pattern as seen from Java. The callback mechanism as provided is very
general but it mostly seems to get used in a standard way.
The question I wish to pose to you is whether the following pattern is
sufficient for all practical cases or whether there are important
use-cases I'm missing.
Assume the *data field maps to an instance of the following Java
listener (and ignore the JNI red tape required)
public interface CollisionListener
{
public int contact (long o1, long o2);
public void addContact (long contact);
}
void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) {
// colliding a space with something
dSpaceCollide2 (o1,o2,data,&nearCallback);
// collide all geoms internal to the space(s)
if (dGeomIsSpace (o1)) dSpaceCollide (o1,data,&nearCallback);
if (dGeomIsSpace (o2)) dSpaceCollide (o2,data,&nearCallback);
}
else {
// colliding two non-space geoms, so generate contact
// points between o1 and o2
int max_contacts = data.contact (o1, o2);
if (max_contacts == 0)
return;
dContact [num_wanted] contact_array;
int num_contact = dCollide (o1,o2,max_contacts,contact_array,skip);
// add these contact points to the simulation
for (int n = 0; n < num_contact; n++)
{
data.addContact (&contact_array[n]);
}
}
}
The Java code will then typically look like:
public class MyCollisionListener implements CollisionListener
{
public int contact (long o1, long o2)
{
return 10; // possibly sensitive to geom types of o1, o2, or their owners
}
public addContact (long contactPtr)
{
Contact contact = new Contact (contactPtr);
contact.getSurface().set...
Joint contactJoint = new ContactJoint (world, contactGroup, contact);
contactJoint.attach (contact.getG1(), contact.getG2());
}
}
From the Java side I expect to rely quite heavily on the collision
category bits to prefilter most potential collisions rather than return
0 in the contact method.
Thanks for your interest,
Dave Lloyd
Short Fuze Ltd
--------------040204000909040800050303
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
Greetings all,<br>
<br>
I've been playing with ODE for a little bit now and have a set of Java
bindings that I will shortly be releasing. I'm currently trying to tidy
up the collision callback which is a bit clumsy through Java. The most
awkward bit (more so than it first seemed) is in providing a contact
array - as things stand I can only easily provide *one* contact which
is not sufficient. Anything more and I run into scope violations or
storage freeing problems. So I've been thinking about refining the
callback pattern as seen from Java. The callback mechanism as provided
is very general but it mostly seems to get used in a standard way.<br>
<br>
The question I wish to pose to you is whether the following pattern is
sufficient for all practical cases or whether there are important
use-cases I'm missing.<br>
<br>
Assume the *data field maps to an instance of the following Java
listener (and ignore the JNI red tape required)<br>
<pre>public interface CollisionListener
{
public int contact (long o1, long o2);
public void addContact (long contact);
}
</pre>
<pre><font>void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) {
// colliding a space with something
dSpaceCollide2 (o1,o2,data,&nearCallback);
// collide all geoms internal to the space(s)
if (dGeomIsSpace (o1)) dSpaceCollide (o1,data,&nearCallback);
if (dGeomIsSpace (o2)) dSpaceCollide (o2,data,&nearCallback);
}
else {
// colliding two non-space geoms, so generate contact
// points between o1 and o2
int max_contacts = data.contact (o1, o2);
if (max_contacts == 0)
return;
dContact [num_wanted] contact_array;
int num_contact = dCollide (o1,o2,max_contacts,contact_array,skip);
</font><font> // add these contact points to the simulation
for (int n = 0; n < num_contact; n++)
{
</font><font> data.addContact (&contact_array[n]);
}
</font><font> }
}
</font></pre>
The Java code will then typically look like:<br>
<pre>public class MyCollisionListener implements CollisionListener
{
public int contact (long o1, long o2)
{
return 10; // possibly sensitive to geom types of o1, o2, or their owners
}
public addContact (long contactPtr)
{
Contact contact = new Contact (contactPtr);
contact.getSurface().set...
Joint contactJoint = new ContactJoint (world, contactGroup, contact);
contactJoint.attach (contact.getG1(), contact.getG2());
}
}
</pre>
>From the Java side I expect to rely quite heavily on the collision
category bits to prefilter most potential collisions rather than return
0 in the contact method.<br>
<br>
Thanks for your interest,<br>
Dave Lloyd<br>
Short Fuze Ltd<br>
</body>
</html>
--------------040204000909040800050303--