Page 1 of 1

Sleeping of Inactive Bodies

PostPosted: Sat Jul 31, 2010 5:50 pm
by slembcke
I know I've drug me feet on this in the past, but I found a data structure that allowed me to implement sleeping without an unnecessary overhead and without the need to add a lot of extra state tracking to Chipmunk. I'm using a data structure called a disjoint set forest to build groups of objects in the space in nearly O(n) time. The code has been merged with trunk and should be relatively bug free. Sleeping has been enabled on demos c, f, r, and s. Idle bodies are drawn in light grey while sleeping bodies are drawn in dark grey.

I've tried to keep the API additions simple:
cpSpace.idleSpeedThreshold - Threshold velocity for a body to be considered idle. The default value of 0 means to let the space pick the threshold based on gravity.
cpSpace.sleepTimeThreshold - If all objects in a group have been idle for at least this duration, then the group will fall asleep. The default value of INFINITY disables the sleeping feature entirely.
cpSpace.staticBody - The space wide static body. When you add a shape or a constraint to the space with NULL for a body, the space will replace it with a pointer to this static body. You can change the data pointer of this body if you want.
cpBodyIsStatic() - Returns true if the body is static.
cpBodyIsRouge() - Returns true if the body has not been added to a space.
cpBodyIsSleeping() - Return true if the body has fallen asleep.
cpBodyActivate() - Wakes up a body and any other body in the group it fell asleep in.

Most importantly, you no longer need to create a static body yourself to attach your static shapes to. You simply use NULL as the body when creating static shapes. In fact, in order to use the sleeping feature you must use a NULL body instead of a "rouge" static body as was the norm up to this point.

Rouge Bodies:
"Rouge body" is just a new name for an old idea, they are bodies that have not been added to a space, but make have joints or shapes in the space that reference them. Because a cpSpace does not control rouge bodies, it prevents any body that is jointed to or touching a rouge body from falling asleep. This is why you must change your existing code to use the NULL body for static shapes instead of a rouge static body if you want to enable sleeping. Fortunately for most people, this should be as simple as changing staticBody = cpBodyNew(INFINITY, INFINITY) to staticBody = NULL.

Additionally, you now only need to use cpSpaceAddStaticShape() and cpSpaceRemoveStaticShape() when adding or removing static shapes attached to a rouge body. If you add a shape attached to NULL, it will automatically be added as a static shape.

Comments, suggestions, critisism?

Re: Sleeping of Inactive Bodies

PostPosted: Sat Jul 31, 2010 6:09 pm
by slembcke
Oh, a couple more things:
  • The code will go out in the next release, which will happen as soon as the documentation is ready. I don't think there are any other changes I wanted to make for 5.3.0. So I just need to squeeze in some time to document it and let it fly.
  • Bodies do not automatically wake up when you change their positions or apply forces to them, etc. They also don't automatically wake up when you change parameters of attached joints.

Re: Sleeping of Inactive Bodies

PostPosted: Sun Aug 01, 2010 8:07 am
by viblo
I think it sounds great! It will be very interesting to try it out :)

A couple of questions:
- What is the reason bodies that are for example moved isn't activated? Performance? Clean implementation?
- How is the performance? When bodies are awake about the same, I guess it will be (much?) better if everything is asleep?

Re: Sleeping of Inactive Bodies

PostPosted: Sun Aug 01, 2010 10:10 am
by slembcke
Not sure I understand your first question. Do you mean why rouge bodies or bodies touching them cannot fall asleep?

The performance is quite good. In the time trials, demos c and f use 90% less CPU time to run 1000 frames. Once objects have fallen asleep they should use very little extra CPU time. The most expensive part of the simulation is solving collisions and sometimes the collision detection, neither of which happen after the objects fall asleep.

Re: Sleeping of Inactive Bodies

PostPosted: Sun Aug 01, 2010 10:45 am
by viblo
Oh, I see I missed some words in the first question :D

What I meant was why bodies do not automatically wake up when for example moved manually?

Re: Sleeping of Inactive Bodies

PostPosted: Sun Aug 01, 2010 12:07 pm
by slembcke
I had code in that would activate bodies when you used the setter functions on bodies or constraints. I took it out because there wasn't a way to make the template macros check if the new value was the same as the old value. If the value didn't change, the body shouldn't be woken up. Maybe that is a silly reason though. If you are setting a value every frame and still want a body to be able to fall asleep, I suppose you can just check it in your own code.

Re: Sleeping of Inactive Bodies

PostPosted: Tue Aug 03, 2010 7:43 am
by dieterweb
Wow, great to see you are still improving chipmunk.

We will definitely use this in our next game.