Physics-based sound

Official forum for the Chipmunk2D Physics Library.
Post Reply
ChypeFlux
Posts: 1
Joined: Sun Aug 21, 2011 3:37 pm
Contact:

Physics-based sound

Post by ChypeFlux »

I've been trying to do some detailed sound reactions to physics contact type situations (e.g., scaling volume based on hit velocities, playing rolling sounds, sliding sounds, etc.) and having limited success.

Prior to searching here, I tried this sort of setup:

1a) an impact has occurred if cpArbiterIsFirstContact is true. ( I save the contact count because...)
1b) an impact has also occurred if cpArbiterGetCount is higher than the count I cached in #1a.
1c) as for hit impact velocities, I just subtract the velocities of the involved shapes...
1d) I check the magnitude against a min threshold and ignore if it's too low.

2) if I'm not an impact from #1, I check the shape type from my wrapper layer. If it was a ball shape, I noticed that radius * body->w is approx equal to the body velocity when the ball is rolling. Perhaps this is just a special case that sort of works?? (well, this only seems to work if the ball is the only shape on the body...)

3) in any other case, I have contacts and so I just "punt" and assume the object is sliding.

This all sort of works to varying degrees in different situations but for starters, angular velocities really hose #1. The velocities between the colliding shapes can be near zero (sound either doesn't pass the min threshold check or the calc'd volume is very small) and yet you visually see what appears to be a substantial hit and you'd expect it to be loud.

Searching the forums, I see tips about using cpArbiterTotalImpulse? I took a look at that but the values coming out of that look kind of insane even with a moderate hit and a single contact. ..And then noticed a simple rolling ball has a comparably low value even if rolling fairly fast. In short, the values aren't exactly making any sense to me.

So I guess the short question is, any tips on where to start with deciphering the collision data?

A slightly longer question would be, how can I get the linear collision velocity...and separately get the angular collision velocity? Or at least, those are the components I'm thinking I need to figure out how to implement my sound scenarios?

Thanks in advance for any tips!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Physics-based sound

Post by slembcke »

Well, I can offer you this old-ish code from Twilight Golf. It works very well. I had a newer-ish sample that I was looking for that used cpArbiterTotalImpulse() but could not find it...

Code: Select all

// velocity of the two surfaces in relation to the collision normal at the collision point
static inline cpFloat
hit_velocity(cpBody *a, cpBody *b, cpVect p, cpVect n){
	cpVect r1 = cpvsub(p, a->p);
	cpVect r2 = cpvsub(p, b->p);
	cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
	cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
	
	return cpvdot(cpvsub(v2_sum, v1_sum), n);
}

// This is a pre-solve callback
static bool
bumpSoundCallback(cpArbiter *arb, cpSpace *space, void *unused)
{
	cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
	cpContact *contacts = arb->contacts;
	
	const cpFloat min = 10.0f;
	const cpFloat max = 300.0f;
	cpFloat nspeed = cpfabs(hit_velocity(a->body, b->body, contacts[0].p, contacts[0].n));

	if(nspeed > min){
		ALfloat volume = fmax(fminf((nspeed - min)/(max - min), 1.0f), 0.0f);
		playSound(bumpSound, volume, 1.0f);
	}
	
	return TRUE;
}
Anyway, to improve upon that, you could make the bumpSoundCallback() into a post-solve callback that uses cpArbiterIsFirstContact() and substitutes cpArbiterTotalImpulse() very similarly to how hit_velocity() is used there. As per the docs, for cpArbiterTotalImpulse() to work, it must be in a post-step callback and elasticIterations must be 0 (deprecated and unnecessary since 5.2 and gone in 6.x anyway). Divide by the timestep to convert it to a force if you aren't using a fixed timestep (which you should be!). The collision impulse/force is going to be pretty big, but it should very dependably tell you how hard objects hit each other. It's the amount Chipmunk applies to correct their velocities 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 11 guests