Problem with gravity and objects not colliding

Official forum for the Chipmunk2D Physics Library.
Post Reply
jer
Posts: 5
Joined: Mon Sep 21, 2009 12:42 pm
Contact:

Problem with gravity and objects not colliding

Post by jer »

Hi;

I'm working on an iPhone app and using chipmunk for physics. I have two basic types of blocks -- those that move, and those that don't. Creating static shapes for those that don't, and regular shapes for those that do. Everything moves just fine that needs to move. The problem is in that objects that move, that collide with objects that don't move, well, pass through the static object as if it wasn't there (slows down if I increase the friction coefficient, obviously, but still passes through). If I turn off gravity, I can still get the objects to move by setting up momentum in one direction using blockBody->v = cpv(...) and this works. The block stops on the static object, won't pass through it. However, when I make the static object disappear, the object does start moving again, but very very slowly, it won't gather momentum like it would with gravity in place.

I'm wondering if anyone has any suggestions as to how to simulate gravity, or better still, make my moving objects stop when they hit static objects.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Problem with gravity and objects not colliding

Post by slembcke »

You're probably setting you space up incorrectly. Can you post some snippets showing how you are setting up your static bodies and shapes?
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
jer
Posts: 5
Joined: Mon Sep 21, 2009 12:42 pm
Contact:

Re: Problem with gravity and objects not colliding

Post by jer »

slembcke wrote:You're probably setting you space up incorrectly. Can you post some snippets showing how you are setting up your static bodies and shapes?
Sure. I set up the space using this method:

Code: Select all

- (void)setupChipmunk
{
	cpInitChipmunk();
	space = cpSpaceNew();
	space->gravity = cpv(0,-200);
	space->elasticIterations = 1;
	cpSpaceResizeStaticHash(space, 400.0f, 40);
	cpSpaceResizeActiveHash(space, 100, 600);
	[self schedule: @selector(tick:) interval: 1.0f/60.0f];
}
And I set up my blocks using this method:

Code: Select all

- (void)createBlock:(Block*)block withAssets:(NSBundle*)assets
{
	BlockSprite* sprite;
	switch(block.blockColour)
	{
		case kBlockColourGreen:
			sprite = [BlockSprite spriteWithFile:[assets pathForResource:@"green" ofType:@"png" inDirectory:@"Blocks"]];
			break;
		case kBlockColourOrange:
			sprite = [BlockSprite spriteWithFile:[assets pathForResource:@"orange" ofType:@"png" inDirectory:@"Blocks"]];
			break;
		case kBlockColourRed:
			sprite = [BlockSprite spriteWithFile:[assets pathForResource:@"red" ofType:@"png" inDirectory:@"Blocks"]];
			break;
		case kBlockColourBlue:
			sprite = [BlockSprite spriteWithFile:[assets pathForResource:@"blue" ofType:@"png" inDirectory:@"Blocks"]];
			break;
	}
	int x = block.bounds.origin.x;
	int y = block.bounds.origin.y;
	sprite.position = ccp(x, y);
	sprite.scaleY = 0.74;
	sprite.scaleX = 0.74;
	[self addChild:sprite];
	
	float halfWidth = block.bounds.size.width / 2;
	float halfHeight = block.bounds.size.height / 2;
	cpVect verts[] = {
		cpv(-halfWidth, -halfHeight),
		cpv(-halfWidth, halfHeight),
		cpv(halfWidth, halfHeight),
		cpv(halfWidth, -halfHeight)
	};
	
	cpBody* blockBody = cpBodyNew(0.00001, cpMomentForPoly([block.mass floatValue], 4, verts, cpvzero));
	blockBody->p = cpv(block.bounds.origin.x, block.bounds.origin.y);
	blockBody->v = cpvzero;
	cpSpaceAddBody(space, blockBody);

	cpShape* blockShape = cpPolyShapeNew(blockBody, 4, verts, cpvzero);
	blockShape->e = 0.9f;
	blockShape->u = 0.9f;
	blockShape->collision_type = 1;
	blockShape->data = sprite;
	if(block.blockColour == kBlockColourOrange || block.blockColour == kBlockColourBlue || [block.gravitySpeed intValue] == 0)
	{
		blockBody->v = cpvzero;
		cpSpaceAddStaticShape(space, blockShape);
	}
	else
	{
		blockBody->v = cpv(0, [block.gravitySpeed floatValue]);
		cpSpaceAddShape(space, blockShape);
	}
	/*
	if((block.blockColour == kBlockColourGreen || block.blockColour == kBlockColourRed) && [block.gravitySpeed intValue] != 0)
		blockBody->v = cpvadd(cpvmult(blockBody->v, 0.7f), cpvmult(cpv(0, -5), 1.0f / 0.1f));
	*/
	sprite.space = space;
	sprite.shape = blockShape;
	[blockSprites addObject:sprite];
}
Note the if statement commented out in the second code snippit if I re-enable it, and change gravity to cpvzero in the setupChipmunk method, I get the behaviour I want, except when I take out the block in the middle (tap on it, three blocks in the view, 2 green ones, bottom one is static, top one is fluid, middle one is orange, and if I tap on it it disappears) then the top green one moves very slowly.

I really would prefer not to have to fake it, and just use gravity instead, so that's my preferred method, but if all else fails, I can fake gravity, so long as I can figure out how to get the cumulative effect, so the object speeds up as it would when using gravity.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Problem with gravity and objects not colliding

Post by slembcke »

You shouldn't be adding bodies that you want to be static to your space. This causes them to fall under the affects of gravity. The shapes attached to it are static and don't get updated to follow it. When something collides with these shapes, it will think they are already moving downwards at a fairly high speed and not push back on the other shape.

To make a static body, give it an infinite mass and moment of inertia and don't add it to the space. Adding it to the space simulates it's movements, something you don't usually want to do for static bodies.

Also, this is probably bad:

Code: Select all

   cpBody* blockBody = cpBodyNew(0.00001, cpMomentForPoly([block.mass floatValue], 4, verts, cpvzero));
You are using a very tiny mass for the object, and using a completely different mass to calculate the moment of inertia.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
jer
Posts: 5
Joined: Mon Sep 21, 2009 12:42 pm
Contact:

Re: Problem with gravity and objects not colliding

Post by jer »

slembcke wrote: To make a static body, give it an infinite mass and moment of inertia and don't add it to the space. Adding it to the space simulates it's movements, something you don't usually want to do for static bodies.

Also, this is probably bad:

Code: Select all

   cpBody* blockBody = cpBodyNew(0.00001, cpMomentForPoly([block.mass floatValue], 4, verts, cpvzero));
You are using a very tiny mass for the object, and using a completely different mass to calculate the moment of inertia.
Thanks for your explanation, it all makes sense now. And yes, that one line of code was leftovers from me tinkering with everything trying to get it to kinda work, I just forgot to revert that back.

Everything is now functioning as it ought to at this stage. Thanks.
Post Reply

Who is online

Users browsing this forum: No registered users and 12 guests