help a noob: getting "ghost collisions"

Official forum for the Chipmunk2D Physics Library.
Post Reply
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

help a noob: getting "ghost collisions"

Post by Johann »

I have a little breakout clone and now that I begun working on two players instead of just one, I'm getting strange ghost collisions. I'll try to explain...

when spawning a ball:

Code: Select all

	this->b[i].cp_shape->collision_type = BRK_COLLISION_TYPE__BALL;
when spawning a player:

Code: Select all

    this->cp_shape->collision_type = BRK_COLLISION_TYPE__PADDLE;
adding the collision handler:

Code: Select all

    cpSpaceAddCollisionHandler(brk->cp_space,
        BRK_COLLISION_TYPE__BALL,
        BRK_COLLISION_TYPE__PADDLE,
        &BRK_collision__ball_2_paddle, NULL, NULL, NULL, NULL);

when reseting a ball:
(this happens to all balls before and between levels, and naturally cp_body and cp_shape get properly initialized as NULL in the ball constructor)

Code: Select all

	if (this->cp_body != NULL)
	{
		cpSpaceRemoveBody(brk->cp_space, this->cp_body);
		cpBodyFree(this->cp_body);
		this->cp_body = NULL;
	}
	if (this->cp_shape != NULL)
	{
		cpSpaceRemoveShape(brk->cp_space, this->cp_shape);
		cpShapeFree(this->cp_shape);
		this->cp_shape = NULL;
	}
the collision handler function

Code: Select all

int BRK_collision__ball_2_paddle ( cpArbiter *arb, cpSpace *space, void *data )
{
	cpShape *ball_shape, *player_shape;
	cpArbiterGetShapes(arb, &ball_shape, &player_shape);
	brk_ball_c *ball = (brk_ball_c *) ball_shape->data;
	brk_player_c *player= (brk_player_c *) player_shape->data;
	if (ball && player)
		ball->last_touched_by = player->index;
	else
	{
		printf ("WTF?! ");
		if (!ball)
			printf (" no ball ");
		if (!player)
			printf (" no player ");
		printf ("\n");
	}
	return true;
}
(note that paddle and player basically mean the same thing, the player IS the paddle)

I end up with a lot of "WTF?! no ball" in stdout (but never on the first level it seems) That means there is one or more lingering shapes that have collision_type == BRK_COLLISION_TYPE__BALL, right? Otherwise that specific collision handler function wouldn't get called by Chipmunk.

But in the single one place in code in the code where a shape gets that collision_type, which I posted above, I also *always* set the data field as a pointer to the ball itself a few lines later... so how come a shape with collision_type == BRK_COLLISION_TYPE__BALL can have NULL as the data field? I just don't get it. Every ball that has a shape or body gets removed from the space and freed during levels... huh?!

It's probably something silly and simple (since it doesn't occur in single player, it seems like it *has* to be a mistake on my part) but I double checked all the obvious places (and the game is still very simple, so there aren't many places to check), plus Chipmunk 5.3 is not even a day old so maybe there's something weird in the removal/freeing of shapes. Nah, it's likely me, who am I kidding :D

Is there a way to get all bodies and/or shapes in a space, so I can draw them and get a better picture of what is going on? Or any ideas what could cause this?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: help a noob: getting "ghost collisions"

Post by slembcke »

That sounds very odd. The new sleeping feature did require changing how shapes are removed, so it's possible I've introduced a new bug, but I thought I tested things pretty carefully by this time.

First of all, you should try running it against the debug version of the Chipmunk library (compiled without the NDEBUG flag) to see if it prints out any warnings or errors. The release version of the library disables the error checks as some of them can be pretty expensive. You should also log your shape pointers when you create, destroy, add or remove shapes. Then when you get bogus shape in the callback you can trace where it came from and what was supposed to happen to it.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

slembcke wrote:First of all, you should try running it against the debug version of the Chipmunk library (compiled without the NDEBUG flag) to see if it prints out any warnings or errors.
Okay, will do that later today.
The release version of the library disables the error checks as some of them can be pretty expensive. You should also log your shape pointers when you create, destroy, add or remove shapes. Then when you get bogus shape in the callback you can trace where it came from and what was supposed to happen to it.
I'm not sure I understand what you mean by "log your shape pointers"? Each ball and paddle/player has a pointer to a body and to a shape each. In the constructor they are set to NULL, when I spawn them, I create a body/shape and set the pointers, when I remove them, I free the body and shape and set the pointers to NULL. There isn't really anything fancy happening in between, so far the ball can't even go out of bounds for example - the *only* time players and balls get spawned is at start of each level, the only time they get destroyed is at the end of each.. that's why it puzzles me so.
when you get bogus shape in the callback
Is there a way to test this? If a shape pointer is pointing to a valid shape I mean. Right now I'm not sure if I'm getting a bogus shape, or if just its user data pointer is NULL (which it shouldn't be, that shouldn't even be possible as explained above).
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: help a noob: getting "ghost collisions"

Post by slembcke »

Logging pointers: (just need to use the %p format sequence)

Code: Select all

printf("Oh look I found a pointer %p, somePointer);
By "bogus" I mean one that either you forgot to remove from the space somehow, or a bug in Chipmunk caused it to not be removed. Otherwise, no, there isn't a definitive test you can run to say if something is a valid shape pointer or not.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

slembcke wrote:First of all, you should try running it against the debug version of the Chipmunk library (compiled without the NDEBUG flag) to see if it prints out any warnings or errors.
Hmm, can't figure out how to do this using CMake.. (I'm using MSYS/MingW) Is there a compiled .dll available somewhere?
slembcke wrote:Logging pointers: (just need to use the %p format sequence)

Code: Select all

printf("Oh look I found a pointer %p, somePointer);
By "bogus" I mean one that either you forgot to remove from the space somehow, or a bug in Chipmunk caused it to not be removed. Otherwise, no, there isn't a definitive test you can run to say if something is a valid shape pointer or not.
well, putting into the collision handler function posted above

Code: Select all

printf ("%p / %p", ball, player);
results in

00000000 / 045ad490

which kinda is the same, and shouldn't be possible, right? Since there can't be a collision between one shape and a NULL shape.... ?
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

I now spawned some particles at the current player position whenever that "ghost collision" occurs -- it turns out it happens when a paddle hits a screen boundary! Those boundaries are (non-static, uh) shapes attached to rogue bodies, so I'll attach them to the static body of the space and see if that resolves it...

However, it's still weird/buggy that Chipmunk calls that collision handler function .. those boundaries don't even have a collision_type set!
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

Johann wrote:I'll attach them to the static body of the space and see if that resolves it...
nope, still the same. oh, and I obviously also was wrong with it not happening on the first level, it happens whenever a paddle hits a boundary period, balls don't seem to have anything to do with it. Weirdness ^ 2!
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

Johann wrote:However, it's still weird/buggy that Chipmunk calls that collision handler function .. those boundaries don't even have a collision_type set!
And just that turned out to be the problem, or rather, the solution, I created a new enum value for boundaries and now explicitly set collision_type of their shapes to that -- it's not used for any collision handlers, but just setting it made the problem disappear.

I wised up to it when I created a new collision function for balls <-> powerups (since those should not collide, and a collision handler that returns false is simpler than creating a new layer for everything else I want powerups to collide with), because then all of a sudden powerups fell through the boundaries, too (although not paddles or balls = weird!)
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: help a noob: getting "ghost collisions"

Post by slembcke »

Well, by default shapes have a collision_type of 0. If you don't explicitly set the value of the first enumerant in your enumeration, it will be 0 implicitly.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Johann
Posts: 11
Joined: Tue Aug 10, 2010 6:08 am
Contact:

Re: help a noob: getting "ghost collisions"

Post by Johann »

I guess that explains it then! :oops:
Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests