Page 1 of 2

Detect touching bodies via Objective-Chipmunk

Posted: Thu Jun 21, 2012 4:25 am
by Greenfly Studios
Currently working on a prototype for the iPhone using cocos2D & Objective-Chipmunk; there are several bodies of different shapes/sizes all piled up (some of which have the same collisiontype.) If I tap a body, I delete that body. Next step is to identify all the bodies touching and deleting all those of the same collision type.

I've looked at the groundingCheck() function from the 2D platformer example using cpBodyEachArbiter but this seems to fall back to C - is there a way of doing this via ObjectiveC?

Re: Detect touching bodies via Objective-Chipmunk

Posted: Thu Jun 21, 2012 1:53 pm
by slembcke
Yes, [ChipmunkBody -eachArbiter]:
http://chipmunk-physics.net/release/Chi ... 673e54235f

(Doxygen doesn't parse blocks apparently, so you might want to take a look at the header instead. The function is more or less the same as the C variant.)

Re: Detect touching bodies via Objective-Chipmunk

Posted: Thu Jun 21, 2012 6:10 pm
by Greenfly Studios
Great stuff but if possible, could I trouble you for a very quick code example? :roll:

Code: Select all

[cBallBody eachArbiter:^(cpArbiter *arbiter) {
            CP_ARBITER_GET_BODIES(arbiter, currentBody, otherBody);
            CP_ARBITER_GET_SHAPES(arbiter, currentShape, otherShape);
            
        }];
Getting somewhat stuck at the first hurdle I'm afraid. Attempts to identify the other bodies / shapes isn't really working nor in ChipmunkBody / ChipmunkShape format from the macro.

Re: Detect touching bodies via Objective-Chipmunk

Posted: Fri Jun 22, 2012 8:03 am
by slembcke
It sounds like you just want something like tihs:

Code: Select all

[cBallBody eachArbiter:^(cpArbiter *arbiter) {
	CHIPMUNK_ARBITER_GET_SHAPES(arbiter, currentShape, otherShape);
	
	if(currentShape.collisionType == otherShape.collisionType){
		ChipmunkBody *body = otherShape.body;
		
		for(ChipmunkShape *shape in body.shapes) [space remove:shape];
		[space remove:body];
	}
}];
Also, depending on the version of Chipmunk you are using, you may have to enable the contact graph manually using space.enableContactGraph = TRUE (enabling sleeping implicitly enables the contact graph). With the latest version of Chipmunk, the contact graph is always enabled.

Re: Detect touching bodies via Objective-Chipmunk

Posted: Fri Jun 22, 2012 12:51 pm
by Greenfly Studios
Brilliant - that was just what I needed. The touching bodies are now disappearing off the screen as they should. I hadn't realised the contact graph hadn't been enabled so the block was never being fired + the extra code helps a lot.

Just programming it now to make it recursive and I'll be good :lol:

Many thanks Scott!

Re: Detect touching bodies via Objective-Chipmunk

Posted: Mon Jun 25, 2012 10:04 am
by Greenfly Studios
Interesting little problem. Code as above works fine, dynamic bodies that are touching are being picked up and deleted. My issue now is static bodies. I create a static body by using [ChipmunkBody staticbody] and then added to a shape:

Code: Select all

self.body = [ChipmunkBody staticbody];
self.shape = [ChipmunkPolyShape boxWithBody: self.body width:100 height:20];

[space addBody: self.body]; // Causes crash
[space addStaticShape: self.shape];
So, here's the problem. Adding a static body crashes Chipmunk. Adding a dynamic body causes platform to drop. Not adding a body means it can't be accessed via te arbiter. Would love your thoughts on this :D

Re: Detect touching bodies via Objective-Chipmunk

Posted: Mon Jun 25, 2012 10:48 am
by slembcke
That should be printing an assertion that static bodies cannot be added to a space. Adding a body to a space means that you want Chipmunk to simulate it (make it fall because of gravity, etc). Static bodies never move or change, and so it's considered an error to add them to the space.

Also FYI: You don't need to call addBody, addShape, etc in Objective-Chipmunk. You can just use add: for everything including composite objects you've made that implement the ChipmunkObject protocol. Also, addStaticShape is deprecated in vanilla Chipmunk (I guess I never marked the method as deprecated in Objective-Chipmunk). A shape is considered static if it's attached to a static body.

Re: Detect touching bodies via Objective-Chipmunk

Posted: Mon Jun 25, 2012 2:57 pm
by Greenfly Studios
The underlying problem is still the issue detecting the touching bodies. Because the body hasn't been added to the space, the static bodies aren't being detected when using the arbiter. What would be the ideal way for the arbiter to detect the 'unresponsive' bodies?

Re: Detect touching bodies via Objective-Chipmunk

Posted: Mon Jun 25, 2012 3:31 pm
by slembcke
I'm confused what the issue is. Are you trying to detect static shapes touching other static shapes? That's not possible with Chipmunk. Static bodies/shapes aren't allowed to collide with each other and don't move so it doesn't track collisions between them.

It sounds like you might want to be using sensor shapes instead.

Re: Detect touching bodies via Objective-Chipmunk

Posted: Mon Jun 25, 2012 4:01 pm
by Greenfly Studios
The static shapes/bodies aren't touching each other. As an example, imagine a rectangle with two circles on top, one circle on each end. The circles are dynamic bodies whereas the rectangle is a static shape. If I tap one of the circles, it should remove the circle, the touching rectangle and then the other circle.

Based on the arbiter code, tapping the static shape will remove it and the two circles will drop. If tapping either circle, it is deleted but the static rectangle doesn't disappear (and additionally, the other circle.) The rectangle doesn't get identified as a body.

If I have a stack of circles, all touching circles are deleted so the recursive system is working. Just trying to find the last part of the puzzle!