How can I add an impulse to specific rigid bodies at rest?

Scenario

Rocks falling down a rocky slope, with a flat surface at the bottom. When they land on the surface, the rocks move slightly before coming to a rest.

GLESDebugDraw shows the bright orange outline turning to a slightly darker orange once a rock comes to a rest, until the rock is agitated by another falling rock.

Question: I would like to add an impulse to the rock once it reaches the rest state. How would I implement that?

• Given that this has been edited, I'm surprised none has provided any kind of comment or answer for this question. – phpN00b Jun 25 '14 at 2:37

If you have sleeping allowed (and the b2_timeToSleep is sufficiently short for your needs) you can use the b2Body::isAwake function to test if a rock is settled.

Pseudo-code:

For body in bodies:
If(body is rock and not body->isAwake()) Then
//Apply impulse
End If
End loop


I've come across this problem before when I was developing some physics code for a college project. I'm going to make an assumption that there is some code handling whether or not your rock is in a rest state. If you don't have this piece of code then it can be implemented as follows:

float positionEpsilon = [EPSILONVAL] // Use to check if the position of the rock has changed by a significant amount

// Update the rock
void UpdateRock(Time delta)
{
changeInPosition = [CURRPOS] - [PREVPOS] // Take the last position from the current position
.
.     // Some code
.
if(changeInPosition < positionEpsilon)
{
// Here you could perform an action on the rock
// or put it to sleep and check if it's asleep
// in another part of the code
}
}


That's a general enough explanation of how I got it working in my project where I just used basic C++ to build the engine. You're using Box2D so it should be much easier to check if a body is asleep using b2Body::isAwake() function.