Separate collision is being called twice

Discuss any Chipmunk bugs here.
Post Reply
runitzme
Posts: 5
Joined: Sun Sep 18, 2011 5:52 pm
Contact:

Separate collision is being called twice

Post by runitzme »

Hello,

I have a peculiar problem that I've been trying to fix for the last 2 days (20 hours total), and I am stumped! :cry:

Here is the problem: one of my separate collision handler is being called twice and I cant figure out why. It is called when the object is in a mid-way collision with another object, and once more when it actually separates. I read that when the object is being removed, the separation handler gets called again but the objects are not being removed. The odd thing is, the collision handler is only called twice when the object is at an positive rotation angle! When it has a negative rotation angle it works fine.

Here is the code snippet for the object:

Code: Select all

...
cpVect square[] = {cpv(-boundaries.width/2,0), cpv(-boundaries.width/2,40), cpv(boundaries.width/2,40), cpv(boundaries.width/2,0)};
    HoverShape = cpPolyShapeNew(GameBody, 4, square, cpv(0,boundaries.height/2));
    HoverShape->sensor = true;
    HoverShape->collision_type = HoverCollision;
    
    HoverShape->data = self;
    cpSpaceAddShape(GameSpace, HoverShape);
    cpSpaceAddCollisionHandler(GameSpace, HoverCollision, CollisionScreenBorder, checkSeparated, NULL, NULL, Separated, NULL);
..
And the object it is colliding into. This object is placed at the screen border and the body is not being put into gamespace because I want game objects to pass through it. It's purpose is just to check if any objects goes fall the screen and throws an event if there is one.

Code: Select all

GroundBody = cpBodyNewStatic();
    
    float radius = 10.0f;
    cpShape *groundShape = cpSegmentShapeNew(GroundBody, lowerLeft, lowerRight, radius);
    groundShape->e = 1.0f;
    groundShape->sensor = true;
    groundShape->u = 1.0f;
    groundShape->collision_type = bCollisionScreenBorder;
    groundShape->layers ^= GRABABLE_MASK_BIT;
    
    cpSpaceAddShape(GameSpace, groundShape);
    
The collision handler:

Code: Select all

static void Separated(cpArbiter *arb, cpSpace *space, void *unused){
    cpShape *hover, *border;
    cpArbiterGetShapes(arb, &hover, &border);
    HoverObj* obj = (HoverObj*)hover->data;
    
    CCLOG(@"called");
}
Can anyone help? Thanks!

Edit
It seems to call the begin collision handler twice too, so it may have ended the collision event and started another one instantaneously?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Separate collision is being called twice

Post by slembcke »

Do you have multiple shapes on a body? Collision callbacks work on a per shape basis not per body. If you need to deal with multiple shapes you need to keep a counter. Increment it for every begin callback and decrement it for each separate. Then you know if a callback is the first or last one to be called.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
runitzme
Posts: 5
Joined: Sun Sep 18, 2011 5:52 pm
Contact:

Re: Separate collision is being called twice

Post by runitzme »

hey slembcke, thanks for your reply. Nope, I don't have multiple shapes...only one shape
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Separate collision is being called twice

Post by slembcke »

The odd thing is, the collision handler is only called twice when the object is at an positive rotation angle! When it has a negative rotation angle it works fine
This still strikes me as odd, but I'm not sure what would be causing that exactly. The winding is correct, so it's not missing collisions due to a bad convex hull or anything.

Other ideas:
Have you tried logging the shape pointers in the callback to make sure that it's actually the same shape pair generating the callbacks? You should definitely NOT be able to get a begin, begin, separate, separate sequence with the same pair. That should be thoroughly impossible as the hash table that stores the collision information uses the pair of shape pointers as a key. It's possible that you could be getting a begin, separate, begin, separate sequence with the same pair though due to some bug that thought they stopped colliding for a frame.

Are you using the sleeping feature at all? Try disabling it you are. There used to be a bug that would cause sensor shapes that fell asleep while in contact with something to call their separate callback, and then call the begin callback again when they woke back up. I have a unit test to catch that specific case, but maybe there is something similar?
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
runitzme
Posts: 5
Joined: Sun Sep 18, 2011 5:52 pm
Contact:

Re: Separate collision is being called twice

Post by runitzme »

I logged the shape pointers as you said, and sure enough it was the same pair generating the collision both times. And nope, I did not use the sleeping function.

Out of desperation, I created a new project with just the two objects and ran through the scenario again. In the new project, there was only one separation collision being called. So i do not know what is causing the double separation in the original project. The only code differences are the ones that do not relate to the two objects at all (user interfaces, other game objects, etc).
runitzme
Posts: 5
Joined: Sun Sep 18, 2011 5:52 pm
Contact:

Re: Separate collision is being called twice

Post by runitzme »

FINALLY! I found out why!

Here is what happens: when the object that is falling out of the screen border, it touches a THIRD object as it falls. The first object keeps touching the 3rd object while going through the 2nd object (the screen border). When it separates from the 3rd object, it triggers the separation collision (the first time). This is why the rotation angle mattered, at different angles it wouldn't be touching the 3rd object. And then when it falls out of the border, it triggers the separation collision handler again (2nd time).

Now the 3rd object has a different collision type so I do not know why it is calling the collision handler for the 1st and 2nd object with the same shapes causing the collision. But when i removed the 3rd object, everything works perfectly. Mission accomplished.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Separate collision is being called twice

Post by slembcke »

Hmm. That sounds very bizarre. If you can make a project to verify and replicate it as a bug, I'd certainly be interested in trying to fix that.
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 3 guests