Disabling momentum transfer

Official forum for the Chipmunk2D Physics Library.
Post Reply
JEisen
Posts: 3
Joined: Sat Dec 24, 2011 9:00 pm
Contact:

Disabling momentum transfer

Post by JEisen »

I'm working on my first experiments using Chipmunk (in fact, it's my first foray into non-text-based games) so I'm trying to use a few of the standard libraries to get to know them better. I should also note, as a caveat, that while I've taken (and passed) basic university-level physics classes, I can't say that I'm great at applying them to full systems (and besides which, it's been a while since I took them.)

Anyway, that's a roundabout way to say that I'm running into a conceptual issue with Chipmunk, and while I know a workable answer would be "Don't use Chipmunk", I'm going with the idea that learning how to force it into the API (or even that it's just not possible) will teach me more about the framework than I'd otherwise get.

So here's the issue. I'm writing a simple Jezzball-like game, where the only objects are walls and bouncing balls. To give it the classic bouncing effect, I'm using no damping and perfect (1.0) elasticity on each ball and the walls. As I place balls into the area, I put it in a random position, set its rotation angle to (rand * (2*PI)), then apply a constant impulse of Vector(cos(angle), sin(angle)).

The problem is that this method works too well -- when a ball hits a wall, it bounces off in a new direction with its proper momentum still intact. But when two balls collide, there's transfer going on, so eventually, I'll have some balls just chugging along slowly and others zipping around the space like rockets. What I'd like to do instead is have the balls ricochet off of each other into the direction they'd go with the realistic method but with constant momentum.

What would be the best way to handle this? Replace the entire collision handler for balls hitting each other? Adding a post_collision handler that corrects it? Something else?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Disabling momentum transfer

Post by slembcke »

I'm currently working on a physics breakout game (for a contract so I can't share the code), but what I did was to reaccelerate the ball towards it's ideal velocity a little each frame. It works really well in practice. You just have to find a suitable acceleration amount so that the physics stays stable, but the ball doesn't look like it slowly accelerates back to normal speed. It's just a matter of tweaking though.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
JEisen
Posts: 3
Joined: Sat Dec 24, 2011 9:00 pm
Contact:

Re: Disabling momentum transfer

Post by JEisen »

Without going into too much code detail, I suppose, what would the formulas look like in those steps? How would I calculate the impulse (or force?) I'd have to apply to get it back to the speed I want?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Disabling momentum transfer

Post by slembcke »

Ok, I trimmed down the code to show just the part you wanted to know. It's actually pretty simple. It uses a feature of Chipmunk that I don't really have properly documented, integration callbacks.

Code: Select all

static void
BallVelocityFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
	// Accelerate ball towards it's normal speed.
	// Start with the body's normal velocity.
	cpVect v = cpBodyGetVel(body);
	
	// Accelerate the ball in this direction towards it's normal speed.
	cpVect v_desired = cpvmult(cpvnormalize_safe(v), BALL_SPEED);
	cpBodySetVel(body, cpvlerpconst(v, v_desired, BALL_ACCEL*dt));
}

// Somewhere you need to do this to set the integration callbacks.
ballBody->velocity_func = BallVelocityFunc;
Basically this function is run for the ball's body each time it needs to update it's velocity. Normally, cpBodyUpdateVelocity() provided by Chipmunk is what is called. It applies gravity, forces and damping to the body. In this case, the only forces we want to apply are to make it accelerate back to it's normal speed. The acceleration we want to apply is constant so we don't even need to calculate a force.

So what the code does is to figure out what the velocity should be and lerp the actual velocity of the body towards the desired velocity using cpvlerpconst() to clamp the acceleration off at a maximum of BALL_ACCEL.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
JEisen
Posts: 3
Joined: Sat Dec 24, 2011 9:00 pm
Contact:

Re: Disabling momentum transfer

Post by JEisen »

I just had a long post written about how that still wasn't working, then I adjusted the numbers and suddenly it all fell into place. It still looks a little unnatural, but I'm justifying it as saying that Jezzball itself represented an unnatural state, and this is just a slightly different unnatural state. It's a little weird to see the balls hit and continue in roughly the same direction at their "normal" speeds, but I'm accepting it. Thanks!
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests