Collision Handler question(s)...

Official forum for the Chipmunk2D Physics Library.
Post Reply
ahlywog
Posts: 16
Joined: Sun Nov 23, 2008 10:43 pm
Contact:

Collision Handler question(s)...

Post by ahlywog »

Hey all,

I'm to the point in my project (first chipmunk project, WEE!!) where I'm beginning to implement collision handlers. The manual explains how to do simple things, but I can't figure out how to associate the colliding shapes with any of MY class functionality.

This is probably something really easy and straight forward, it usually is in my case, but I just can't figure it out.

Thanks in advance.

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

Re: Collision Handler question(s)...

Post by slembcke »

Sounds like you are looking for the the user data properties. Easiest to explain with an example maybe:

Code: Select all

cpShape *shape = ...;
cpShapeSetUserData(shape, myGameObjectThatOwnsThisShape);

cpSpaceAddCollisionHandler(space, typeA, typeB, CollisionBegin, NULL, NULL, NULL, myGameStateObject);

static cpBool CollisionBegin(cpArbiter *arb, cpSpace *space, void *ptr){
  // the last argument to a collision handler function is the last value passed to cpSpaceAddCollisionHandler()
  GameState myGameStateObject = (GameState *)ptr;

  CP_ARBITER_GET_SHAPES(arb, shape1, shape2);

  // Now you can retrieve the user data pointers on your shapes:
  GameObject *myGameObjectThatOwnsThisShape = (GameObject *)cpShapeGetUserData(shape1);
  // Now you can get access back into your game object/state code.
}
Pretty much every Chipmunk object has a user data pointer, including arbiters and spaces even. You can use them for whatever you want, but I would recommend storing pointers back to whatever object owns them or is responsible for them. I usually also set the data pointer on shapes to the same object as the body they are attached to. Having a common base class is also a pretty good idea.

Some people use the user pointers on bodies or shapes to store the pointer to the sprite that they are associated with. Then after stepping the space, they iterate the bodies and copy the body position to the sprite. I consider this to be a fairly bad idea as it uses up the data pointer for what is often just a "dumb" sprite object. Then later when you want to use collision handlers you only have the pointer to the graphics object and not something that you can use for game logic. People do this because many sprite engines don't let you easily override sprite rendering behavior or because it's easier than storing their own list of bodies and sprites to synchronize.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ahlywog
Posts: 16
Joined: Sun Nov 23, 2008 10:43 pm
Contact:

Re: Collision Handler question(s)...

Post by ahlywog »

Ok I did what you said and now it's kinda working. I set data to the pointer of its parent object and followed your code and now it seems to be working...kinda.

I'm trying to use a sensor as the basis for gravity in my project. The sensor shape is bound to whatever object I want to have gravity and it works it's magic on whatever objects it collides with. It seems to work for about 5 time step cycles and then stops. After that the collision handler isn't even called.

The Codezzzzzz

Code: Select all

#define COLLISION_DEFAULT 0
#define COLLISION_PLANETARY_GRAVITY 1

cpSpaceAddCollisionHandler(Game_Space, COLLISION_PLANETARY_GRAVITY, COLLISION_DEFAULT, Planetary_Gravity_To_Default, NULL, NULL, NULL, NULL);

static int Planetary_Gravity_To_Default(cpArbiter *arb, cpSpace *space, void *unused)
{
    CP_ARBITER_GET_SHAPES(arb, a, b);
    GravityClass* GravityObject = (GravityClass *)cpShapeGetUserData(a);
    GravityObject->ApplyGravityToObject(b->body);
    return 0;
}
Thanks in advance.
ahlywog
Posts: 16
Joined: Sun Nov 23, 2008 10:43 pm
Contact:

Re: Collision Handler question(s)...

Post by ahlywog »

Ok, playing with it some more and I'm seeing a trend. I was using a circle shape for my "gravity well" and I had started off with it big enough to cover the screen. All objects on the screen would then have 5 collisions with the sensor, each, and then stop colliding with it.

I brought the radius in so it was only a little bigger than the body the sensor is bound too and the collision handler only seems to be called when two shapes initially contact, not while they're overlapping, and never again until those shapes break contact and then collide again...
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Collision Handler question(s)...

Post by slembcke »

So cpSpaceAddCollisionHandler() takes four callback pointers. The one you are passing is the begin callback and is only called the first time a pair of objects collide. If you want a callback every frame, you want to use the pre-solve callback instead:
http://chipmunk-physics.net/release/Chi ... nCallbacks
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ahlywog
Posts: 16
Joined: Sun Nov 23, 2008 10:43 pm
Contact:

Re: Collision Handler question(s)...

Post by ahlywog »

Awesome, that fixed it. You are a scholar and a gentleman, Slembcke. Thank you.

For future reference what situations are the other two callbacks, postSolve and Seperate, used for?
Post Reply

Who is online

Users browsing this forum: No registered users and 14 guests