cpArbiterTotalImpulse problems

Official forum for the Chipmunk2D Physics Library.
Post Reply
doso73
Posts: 4
Joined: Wed Jun 16, 2010 7:35 am
Contact:

cpArbiterTotalImpulse problems

Post by doso73 »

Hi,

I'm trying to get the collision intensity in order to adjust the volume of my collision sounds. The function to use seems to be cpArbiterTotalImpulse , obtained from within the postCallback. However, the impulse I get is 0. Delving deeper, I found that the impulse is 0, because the arbiter's jnAcc is set to 0 here (cpArbiter.c, line 255):

// Calculate and clamp the normal impulse.
cpFloat jn = -(con->bounce*eCoef + vrn)*con->nMass;
cpFloat jnOld = con->jnAcc;
con->jnAcc = cpfmax(jnOld + jn, 0.0f);

stepping in the debugger reveals that for my typical collisions, jnOld + jn is in fact < 0. Now I don't really understand this code, but it seems strange to me to hard clamp jnAcc to 0 when the relative velocities are < 0, but I assume there's a good reason. However, cpArbiterTotalImpulse gives me zero, while the collision happen just fine. Is there something else that I could be missing? All I do is register the post callback. Should I also do a pairing function, set a bias or something like that?

thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: cpArbiterTotalImpulse problems

Post by slembcke »

This was never a problem initially. :( I'm guessing that you have elastic iterations enabled. It's a known bug that it will cause it to return incorrect results: http://code.google.com/p/chipmunk-physi ... _Functions

I'm currently looking into a good way to fix this. One suggested way to do it is to cache the elastic impulse separate from the regular impulse, but that would further inflate the already large contact struct. I'm hoping that I don't have to do that.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ShiftZ
Posts: 114
Joined: Sat Mar 07, 2009 7:23 am
Contact:

Re: cpArbiterTotalImpulse problems

Post by ShiftZ »

From my experience, a good solution comes in head only after a bad solution is implemented. ;)
doso73
Posts: 4
Joined: Wed Jun 16, 2010 7:35 am
Contact:

Re: cpArbiterTotalImpulse problems

Post by doso73 »

Hi,

In fact, I left elasticIterations at its default 0. Could there be other trivialities I am missing? My objects bounce perfectly, so the impulse calculation is correct. Do I need to enable something?

thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: cpArbiterTotalImpulse problems

Post by slembcke »

Hrm. If elastic iterations is 0, then it should be working correctly. I'm not sure what the issue would be then. You are sure you're reading it out of a postSolve() callback and not a preSolve() one?
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
doso73
Posts: 4
Joined: Wed Jun 16, 2010 7:35 am
Contact:

Re: cpArbiterTotalImpulse problems

Post by doso73 »

I think I do everything as it should be done.

this is my postSolve function:

Code: Select all

static void BallBallCollisionPost(cpArbiter *arb, cpSpace *space, void *inSequencer){
		cpShape *a, *b; 
		cpArbiterGetShapes(arb, &a, &b);
		cpVect v = cpArbiterTotalImpulse(arb);
		cpFloat impulse = cpvlength(cpArbiterTotalImpulse(arb));
		if(cpArbiterIsFirstContact(arb)){
		      NSLog(@"-----> impulse: %f", impulse);
		      PlaySound(1, impulse, (EC::Sequencer*)inSequencer);
	  }else{
	     NSLog(@"impulse: %f", impulse);
	  }
}
in my scene's init I call:

Code: Select all

    space = cpSpaceNew();
    (snip)
   space->elasticIterations = space->iterations;   // so using #define DEFAULT_ELASTIC_ITERATIONS 0 , space->elasticIterations = DEFAULT_ELASTIC_ITERATIONS; 
   (snip)
    cpSpaceAddCollisionHandler(space, kBallCollision, kBallCollision, NULL, NULL, BallBallCollisionPost, NULL, mSequencer);
the sprites are added like this:

Code: Select all

- (void) AddBall:(CGPoint)inPoint{
	CCSprite* newBall = [CCSprite spriteWithFile:@"circel-kruis40.png"];
	[newBall retain];
	
	float ballRadius = 20.5;
	
	[self addChild:newBall z:1];
	newBall.position = inPoint;
	
	cpBody *body = cpBodyNew(1.0f, cpMomentForCircle(1.0f, ballRadius, ballRadius, CGPointZero));
	body->p = inPoint;
	cpSpaceAddBody(space, body);
	
	cpShape* shape = cpCircleShapeNew(body, ballRadius, CGPointZero);
	shape->e = 0.5f; shape->u = 0.5f;
	shape->data = newBall;
	shape->collision_type = kBallCollision;
	cpSpaceAddShape(space, shape);
	
	mBallShapes.push_back(shape);	
}
and, the collisions themselves work perfectly (graphically).

thanks for your responses,

doso
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: cpArbiterTotalImpulse problems

Post by slembcke »

Code: Select all

space->elasticIterations = space->iterations;
I'm guessing that is your problem right there. I'm not sure I follow what your comment is saying, but elastic iterations is certainly not 0 then. You only need elastic iterations if you want elastic things to stack. If all you have is bouncing balls, you don't really need them.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
doso73
Posts: 4
Joined: Wed Jun 16, 2010 7:35 am
Contact:

Re: cpArbiterTotalImpulse problems

Post by doso73 »

Ah, so I continuously misread that line... It now works fine; thanks for your continued support!
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 13 guests