Game Development Reference
In-Depth Information
If currentMotion drops below the sleep epsilon value, but in the previous few frames
the object has been moving a great deal, then the overall motion value will still be
high. Only when an object has spent a while not moving will the recency-weighted
average drop below the epsilon value.
Because objects can move at very high speeds (and because we are working with
the square of these speeds), a brief burst of speed can send the RWA sky high, and
it will take a long time to get back down to reasonable levels. To prevent this, and to
allow objects to fall asleep faster, I have added code to limit the value of the RWA:
if (motion > 10*sleepEpsilon) motion = 10*sleepEpsilon;
The bias of the RWA should be dependent on the duration of the frame. Longer
frames should allow the current value to affect the RWA more than short frames.
Otherwise objects will fall asleep faster at faster frame-rates.
We can accomplish this in the same way we did for damping:
real bias = real_pow(baseBias, duration);
where baseBias is the bias we'd expect for one-second frames. I've typically used val-
ues around 0.5 to 0.8 here, but again some experimentation is needed.
Wa k i n g O b j e c t s U p
We have already seen that objects can be awakened manually. We also need to wake
objects up when they must respond to new collisions. Collisions between sleeping
objects, as we have seen, are generated and automatically ignored by the collision
resolution system.
When a new object (the player, for example, or a projectile) comes along and
collides with a sleeping object, we want all objects that could be affected by the col-
lision to wake up. For any particular collision this means that if one body involved is
asleep and the other is awake, then the sleeping body needs to be awakened. We add
a method to the Contact class to accomplish this:
Excerpt from src/contacts.cpp
void Contact::matchAwakeState()
// Collisions with the world never cause a body to wake up.
if (!body[1]) return;
bool body0awake = body[0]->getAwake();
bool body1awake = body[1]->getAwake();
// Wake up only the sleeping one.
if (body0awake ^ body1awake) {
Search Nedrilad ::

Custom Search