box2d preSolveContact

if you have similar requirements:

– can’t use a sensor, because you want the object to still react to some other objects in the world
– can’t use collision filter, because you want to listen to the contact

you can use preSolveContact.

An example, where I want to remove the node as I’m about to hit it. Unlike beginContact, preSolve may be called many times on a single colision, so once we have the class from the presolve contact node’s userData, we set a isDead property of that class to true so that we don’t try and remove the same node from the box2d world many times.

Example:

-(void) preSolveContact:(b2Contact*)contact  manifold:(const b2Manifold*) oldManifold
{
	b2WorldManifold worldManifold;
	contact->GetWorldManifold(&worldManifold);
	b2Fixture *fixtureA = contact->GetFixtureA();
	b2Fixture *fixtureB = contact->GetFixtureB();
	NSAssert( fixtureA != fixtureB, @"preSolveContact bug");
	
	b2Body	*bodyA = fixtureA->GetBody();
	b2Body	*bodyB = fixtureB->GetBody();
	NSAssert( bodyA != bodyB, @"preSolveContact bug");
	b2Body *otherBody = (bodyA == body_) ? bodyB : bodyA;
	b2Fixture *otherFixture = (bodyA == body_) ? fixtureB : fixtureA;
	
	if( !otherFixture->IsSensor() ) {
		BodyNode *bNode = (BodyNode*)otherBody->GetUserData();
		Class tClass = [Tank class];
		
		if([bNode isKindOfClass:tClass])
		{
			contact->SetEnabled(false);
			Tank *t = (Tank*)bNode;
			
			if(!t.isDead) {
				t.isDead = YES;
				[arrayTanksToRemove_ addObject:t];
			}
		}	
	}
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: