Enhancing collision callbacks.

Discuss new features and future development.

Would you like this functionality:

Sooner! I have awesome uses for this.
5
100%
Later. Please don't break my code that relies on trunk!
0
No votes
 
Total votes: 5

User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Enhancing collision callbacks.

Post by slembcke »

I've been toying around with some new ideas for collision callbacks. I've attached a patch file for trunk with a quick mockup of the proposed changes.

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);
There are way to many parameters there. Every time I want to write one of those I've had to copy paste the prototype to be able to remember them all. A lot of the time I don't even use any of the arguments, and most of the time I don't use anything more than the shapes. Enter the new collision callback. Simpler and easier to remember.

Code: Select all

typedef int (*cpCollFunc)(cpArbiter *arb, struct cpSpace *space, void *data);
Now an explanation of why this is better: With the new post step callback functionality you can add callbacks that are called at the end of a step to do things like safely remove colliding shapes. Another neat potential usage is retrieving the size of a collision impulse in a post step function to calculate falling damage or the like. To do that, you would have had to pass the space as your user data parameter. Now it's just passed to you regardlessly.

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;
}
This would obviously break existing collision callbacks. I can't easily write in compatibility for it either. A wrapper function that calls the old style function would have to allocate a context struct that held the old function and old data pointer. There would have to be logic to free that struct if you remove an old style callback. Converting code that has old style callbacks would be as easy as pasting over the new arguments and throwing a macro that defines the proper variables as the first line to the function.

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.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
viblo
Posts: 206
Joined: Tue Aug 21, 2007 3:12 pm
Contact:

Re: Enhancing collision callbacks.

Post by viblo »

As I don't use trunk yet (or, pymunk doesnt use trunk) I haven't voted, but I say go for it! :) With the release cycle of chipmunk it feels like its better to take the hit now, otherwise we never know when/if it will happen. After all, it looks like it's quite easy to convert old code to use the new callback anyway.
http://www.pymunk.org - A python library built on top of Chipmunk to let you easily get cool 2d physics in your python game/app
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Enhancing collision callbacks.

Post by slembcke »

Ugh. I had a very nice and long post typed up when my F%$#@ing wireless router died. It's barely a year old I think. The wireless stopped responding at least 6 months ago, but at least the ethernet still worked... until now. Two wireless routers to die on me in 3 years. I guess I'll be asking for a new one for Christmas. (end rant)

The grumpy short version of my last post:
I added sensors. Basically the same as Box2D sensors or Unity3D trigger colliders.
I decided on a name and interface for separation functions.
Made a new svn branch for the experimental changes: https://chipmunk-physics.googlecode.com ... nd_sensors
See the pyramid stack demo for a contrived example of both.

(mutters angrily about wireless routers)
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
dieterweb
Posts: 176
Joined: Fri Feb 27, 2009 7:12 am
Location: Germany
Contact:

Re: Enhancing collision callbacks.

Post by dieterweb »

It is great to see that you are working again on your fantastic library.

I will add your new api enhancements too our project soon.

Thanks,
Thomas
Visit our game Blog: [url]http://zombiesmash.gamedrs.com[/url] or follow us on twitter: [url]http://twitter.com/zombiesmash[/url]
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Enhancing collision callbacks.

Post by slembcke »

Ok. Made it a bit more complicated, but much better I think. Pretty sure this will be the new API going forward as well.

Instead of a single collision callback to handle things through, I was talking with one of the Box2D devs and Chipmunkified what they are doing in their next version. Now instead of a single function, there are 4 collision events that you can plug callbacks into:
  • begin - Called the first step that two shapes collide. You can reject collisions from this callback.
  • preSolve - Called every frame before the impulse solver runs. This is basically equivalent to the current single callback, but I shuffled some calculations around so you can override the friction, elasticity, and surface velocity calculations if the default ones don't quite do what you want. You can reject collisions from this callback as well.
  • postSolve - Called every frame after the impulse solver runs. The calculated impulse values for all collisions can be retrieved here.
  • separate - Called as soon as the shapes stop touching.
All of these callbacks are passed the space, collision object (cpArbiter), and a custom data pointer. You don't have to implement all of them, and if you only want to replace the functionality that cpSpaceAddCollionPairFunc() provided, you need only to provide a preSolve callback and send NULL for the rest.

I'm thinking about adding pre/post solve functions to joints as well. Could be very useful for animating joint parameters or detecting when to break and remove joints from the space.

Check out the experimental branch if you want to try it out:
https://chipmunk-physics.googlecode.com ... nd_sensors

I'll probably be merging the changes into trunk shortly however.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
Tam Toucan
Posts: 141
Joined: Tue Jun 23, 2009 4:26 pm
Contact:

Re: Enhancing collision callbacks.

Post by Tam Toucan »

That sounds very nice. Great work. BTW it prompts for a username/password with the google code link.
dieterweb
Posts: 176
Joined: Fri Feb 27, 2009 7:12 am
Location: Germany
Contact:

Re: Enhancing collision callbacks.

Post by dieterweb »

Sounds great!

Is the begin callback called before layers and groups of the two colliding shapes are tested?

Thomas
Visit our game Blog: [url]http://zombiesmash.gamedrs.com[/url] or follow us on twitter: [url]http://twitter.com/zombiesmash[/url]
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Enhancing collision callbacks.

Post by slembcke »

No, only if the objects actually are tested for a collision and are overlapping. The groups and layers are done first as it's much less expensive than doing a full collision check. I'm not quite sure why you would want that, but it sounds like you want a sensor perhaps. A shape that only calls callbacks but never generates collisions. It was a small mention above, but I've added those too. ;) It took all of like 3 lines of code. Can't believe I waited so long to get around to that one.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
dieterweb
Posts: 176
Joined: Fri Feb 27, 2009 7:12 am
Location: Germany
Contact:

Re: Enhancing collision callbacks.

Post by dieterweb »

So, what is the difference between the begin and preSolve callbacks?

I saw that with the sensors,
Will try them, when I find time to update to the current trunk.

Thomas
Visit our game Blog: [url]http://zombiesmash.gamedrs.com[/url] or follow us on twitter: [url]http://twitter.com/zombiesmash[/url]
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Enhancing collision callbacks.

Post by slembcke »

begin is called only the very first step that things collide, preSolve is called every frame that they are touching.

I went ahead and merged the changes back into trunk. I should have some downtime this week from contract work and plan on going nuts trying to get the documentation updated so I can do a proper new release. \o/
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests