Cocos2dx+Chipmunk: Fully elastic collision between moving bodies

I'm using Cocos2dx and the built in Chipmunk physics engine, and currently I've got my PhysicsBodys' materials set up with:

Density=0
Restitution=1
Friction=0


in order to get fully elastic collision, and keep moving bodies moving at a constant speed. This works great if they collide against a static element, like a wall, not so much if they collide with other moving objects.

I'm moving these bodies by applying an initial force:

Vec2 velocity = moveDirection.getNormalized()*moveSpeed - myPhysicsBody->getVelocity();
Vec2 newForce = myPhysicsBody->getMass()*velocity / deltaTime;
myPhysicsBody->applyForce(newForce);


So I'm guessing that even though their materials would result in fully elastic collisions, the moving objects both carry an impact force, this modifies the resulting force into one with different magnitude? All these moving bodies have the same mass.

Currently I'm manually catching the impact start and manually generating the resulting force in the right directing, and using the object's speed to apply it with the same previous magnitude, effectively overriding Chipmunk's collision resolution.

Is this the best way to do this, or can I configure my bodies in a way that allows Chipmunk collision resolution to achieve the same effect? I'm a bit rusty on my physics.. heh..

1 Answer

It is now quite some time after the original question was asked; Chipmunk shapes have a property called "elasticity" which is a number from 0 to 1. Setting it to 1 for both bodies you want to collide will ensure perfectly elastic collisions.

However, you mentioned that you want to "keep moving bodies moving at a constant speed". This is physically incorrect behaviour. Imagine billiard balls which are a close real-life approximation of elastic collision; depending on the collision angle, the resulting speeds can be very different. Or imagine Newton's cradle, where the collisions cause one ball to have some speed whilst the other to remain stationary.

Instead, you will have to override the physics engine after collisions occur. You could do this by using cpBodySetVelocity:

cpVect speed = cpBodyGetVelocity(mybody);
cpVect newspeed = cpvmult(cpvnormalize(speed), myspeed);
cpBodySetVelocity(mybody, newspeed);