Basically, it would simplify and greatly increase the usefulness of callbacks. The function prototype of the old collision callbacks looked like this:
Code: Select all
typedef int (*cpCollFunc)(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data);
Code: Select all
typedef int (*cpCollFunc)(cpArbiter *arb, struct cpSpace *space, void *data);
Another feature that has been requested a couple of times was getting event callbacks when objects start and stop touching. Chipmunk stored this information internally, but it was locked up in the arbiter structs and was very hard to get at from within a callback. Being passed both the space and the arbiter allows you to check if the collision is brand new. The space also filters out old cached collision data stored in the arbiters each step. By adding a function pointer to the arbiter struct, it can call back into your code if a collision happened last step, but not this one.
Code: Select all
static void
untouch(void)
{
printf("untouched a wall\n");
}
// This function has existed for a while, but was not useful until now really
cpVect cpContactsSumImpulses(cpContact *contacts, int numContacts);
static void
printCollisionImpulse(cpArbiter *arb, void *unused)
{
cpVect j = cpContactsSumImpulses(arb->contacts, arb->numContacts);
printf("Collision impulse:%s magnitude:%f\n", cpvstr(j), cpvlength(j));
}
static int
collision(cpArbiter *arb, cpSpace *space, void *data){
// The old arguments would still be easy to get. I'd probably write helper/getter functions for these.
// int swapped = arb->swappedColl;
// cpShape *a = (swapped ? arb->b : arb->a);
// cpShape *b = (swapped ? arb->a : arb->b);
// cpContact *contacts = arb->contacts;
// int numContacts = arb->numContacts;
// cpFloat normal_coef = (swapped ? -1.0 : 1.0);
// Now for some neat new stuff
if(space->stamp == arb->stamp){ // if these are equal, the collision is brand new
printf("Just touched a wall\n");
// Need to come up with a name and some useful arguments, but arb->func() will
// be called when the objects untouch.
arb->func = untouch;
// Let's register a post step callback to further process the arbiter
cpSpaceAddPostStepCallback(space, (cpPostStepFunc)printCollisionImpulse, arb, space);
} else {
// This collision is not brand new, do something else maybe?
}
return 1;
}
Would people using trunk rather have this functionality sooner or should I delay this until the next major revision? Honestly I have no idea when that will be either.