Programatic shape winding - Not colliding with Segment

Official forum for the Chipmunk2D Physics Library.
Post Reply
marcond
Posts: 5
Joined: Wed Jul 22, 2009 10:13 pm
Contact:

Programatic shape winding - Not colliding with Segment

Post by marcond »

I have chipmunk working wonderfully! So awesome :) Bullets collide with Enemies etc. When I collide with an enemy, I add its body to the space. Until then, it's a static shape, and I'm doing a static rehash position as I run Cocos2d Actions on the Sprite etc. This all works! The enemy is hit, and I add him to the space (where chipmunk takes over)

My problem, is these enemy bodys do not collide with my "floor" segment!! arg!! I tried reversing the vector coordinates, but nothing seems to work. Actually today was the first time I read about "winding" issues hah.. I can see it's been a headache for many with cocos2d world coords. But i've tried several tips from other posts, no luck.. Here's the code that generates the enemy Body/Shape from the Cocos2d Texture of the given sprite.

Code: Select all

-(void) SetupEnemyShapeAndBody
{
	CGRect rec = [main_sprite textureRect];
	
	float width = rec.size.width;
	float height = rec.size.height;
	
	float halfwidth = width / 2;
	float halfheight = height / 2;
	float nhalfwidth = halfwidth * -1;
	float nhalfheight = halfheight * -1;
	
	int num = 4;
	CGPoint verts[] = {
		ccp(nhalfwidth,nhalfheight),
		ccp(nhalfwidth, halfheight),
		ccp( halfwidth, halfheight),
		ccp( halfwidth,nhalfheight),
	};
	
	body = cpBodyNew(10.0f, cpMomentForPoly(1.0f, num, verts, CGPointZero));	
	body->p = ccp(main_sprite.position.x, main_sprite.position.y);
	shape = cpCircleShapeNew(body, halfwidth, CGPointZero);
	shape->e = 1.0; shape->u = 1.0;
	shape->data = (void*)self;
	shape->collision_type = 1;
	shape->group = 1;
	
	cpSpaceAddStaticShape(space, shape);
}
That should all be straightforward! Like I said, everything appears to work nicely! the bullets will collide etc. When they DO collide, I do this:

Code: Select all

cpSpaceAddBody(space, body); //if not added already
For the segment, I do this:

Code: Select all

- (void) initChipmunk
{
	cpInitChipmunk();
	space = cpSpaceNew();
	space->gravity = ccp(0, -100);
	space->elasticIterations = 10;
	
	cpSpaceResizeStaticHash(space, 60.0, 1000);
	cpSpaceResizeActiveHash(space, 60.0, 300);
	
	staticBody =  cpBodyNew(INFINITY, INFINITY);
	//staticBody->p = ccp(0,0); should I be doing this?
	
	cpShape * shape;
	shape = cpSegmentShapeNew(staticBody, ccp(0,0), ccp(1000,0) , 0);

	shape->e = 0.5f; shape->u = 1.0f;
	shape->collision_type = 0;
	cpSpaceAddStaticShape(space, shape);
	
	cpSpaceAddCollisionPairFunc(space,1,2, &bulletCollision, self); 
	cpSpaceAddCollisionPairFunc(space,0,1, &platformCollision, self);
	
	[self schedule: @selector(step:)];
}
Lastly, the update stuff:

Code: Select all

-(void) step: (ccTime) delta {
	cpSpaceHashEach(space->staticShapes, &eachShape, NULL); 
	cpSpaceHashEach(space->activeShapes, &eachShape, NULL);
	cpSpaceRehashStatic(space);
	int steps = 2;
	CGFloat dt = delta/(CGFloat)steps;
	for(int i=0; i<steps; i++){
		cpSpaceStep(space, dt);
	}
Very sorry for so much code/postage.. Really struggling to get this working, desperate times as I near midnight :)

PS, I love this forum. Code blocks are real slick

-Marco
marcond
Posts: 5
Joined: Wed Jul 22, 2009 10:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by marcond »

Bump, spent this past weekend reading other forums on here.. tried a few more last resort ideas with no luck.. Such as putting walls on all sides of the landscaped screen and none of them generate collisions with bullets OR the enemy bodies. ARG still need help, frustration++
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by slembcke »

It looks like you are adding the dynamic versions of the bodies as static shapes. Static shapes do not generate collisions with other static shapes because they aren't really supposed to be moving anyway.

Also, it might be faster to add you enemies as dynamic shapes instead of rehashing the static hash every frame. The entire point of the static hash is that you don't need to update the collision data of objects that are not moving, nor do you have to generate collisions between them. While you can update the static hash for things that happen ever once in a while like opening a door or something like that, you don't really want to do it every frame. Add you enemy shapes as normal shapes and use layers and/or groups to act as a fast filter from processing collisions between enemies and static shapes.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
marcond
Posts: 5
Joined: Wed Jul 22, 2009 10:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by marcond »

slembcke, wow I don't know how I missed that. I never move the shape from static to active once they are "hit". All I do is add the body. Thank you!

I have read that using the static rehash comes at a cost.. Honestly the only reason they are static at first, is so that I can move the enemies around myself.. Using Cocos2d Actions or whatever else I see fit. Then the enemies get hit and I make them active (well, I wasn't.. you spotted my error :D).. They only visually appeared to be active.

Is there an easier way to gain "manual" control of a shape/body, such that it would still generate collisions and not have its position change because of the physics simulation? I tried a couple other ways, but the forces kept adding up and changing my positions/rotations (aka, you would see a single sprite bouncing between 2 points).. either i rename my game to iSeizure or use static rehashes for enemies i want to control manually heh


Thank you very much either way.. Wonderful job you've done :) I will surely donate in the near future.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by slembcke »

You can move them around using your own code if you don't add the bodies to the space. This sounds weird not to add it, but the reason to add a body to a space is only so that the physics engine will apply forces and gravity to the body. If you want to move the body around yourself, just make sure that you keep the velocity and position changes in sync or collisions will act odd because they are detected by position and handled using velocity.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
marcond
Posts: 5
Joined: Wed Jul 22, 2009 10:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by marcond »

Funny thing is that i'm over on the Cocos2d iPhone forums more often, and there are tons of people looking to more or less turn the physics "off" temporarily on a body. Be able to quickly bounce between:

2d Graphics engine moving the body around (body determines at what velocity you're moving it at on its own as a f(dt) = velocity etc)
Chipmunk has full control

seems to be the biggest thing people grapple with.. integration with 2d engine positioning.

PS that fix worked slembcke, Verified last night. Thanks - Marco
JC13
Posts: 6
Joined: Mon Jun 08, 2009 11:23 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by JC13 »

I'm doing something similar in my code, where I'm adding the shape, but not adding the body to space. The problem I'm getting now is that I seem to have a memory leak.

I think the problem is because the body doesn't get freed when I call:

Code: Select all

cpSpaceFreeChildren(space);
cpSpaceFree(space);
since the bodies haven't been added to the space. At least, that's what I think is happening... does that make sense? any work arounds?

The only thing I can think of is to iterate through all the shapes when dealloc is called, and then use

Code: Select all

cpBodyFree(body)
to remove all the bodies manually. Is there an easier way?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Programatic shape winding - Not colliding with Segment

Post by slembcke »

cpSpaceFreeChildren() isn't really meant to be super generally useful. Other than the primitive allocate and free stuff that Chipmunk provides, that is the only other memory management function. You just need to hold onto a copy of the pointer somewhere else so you can free it later. Or as a hack you can give your static bodies do-nothing position and velocity update functions and add them to the space anyway.
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 9 guests