开发者

instantly sleeping stack of dynamic objects

My scene has a number of stacks of dynamic objects. When the simulation starts, it takes a while for these to "resolve" before they become sleeping islands. This affects performance significantly for the first few s开发者_JS百科econds.

Are there techniques for arranging stacks so that they immediately sleep?

I'm using PhysX.


You can use

NxActor::putToSleep();

on startup. This will dramatically increase scene performance. However, if there are misplaced objects on your stack (i.e. a flying cube) it won't fall down until some another dynamic objects hits on it.

This approach does not seem to work on actively moving objects. For example if my dynamic object is moving with speed 5m/s on my scene and if I try to force it to sleep, putToSleep won't work (even if I make set the velocity of the object to 0 first, then put it to sleep)

Here is a workaround to if you need to force sleep and disable a dynamic actor.

void setDynamicActorState(NxActor& actor, bool disabled)
{
    if (nxActor.getNbShapes() > 1)
    {
        for (int i = 0; i < nxActor.getNbShapes(); i++)
        {                   
            nxActor.getShapes()[i]->setFlag(NX_SF_DISABLE_COLLISION, disabled);
        }               
    }
    else
    {
        if (disabled)
            nxActor.raiseActorFlag(NX_AF_DISABLE_COLLISION);
        else
            nxActor.clearActorFlag(NX_AF_DISABLE_COLLISION);
    }

    for (int i = 0; i < nxActor.getNbShapes(); i++)
    {
        nxActor.getShapes()[i]->setFlag(NX_SF_DISABLE_SCENE_QUERIES, disabled);
    }

    if (disabled)
    {
        nxActor.raiseBodyFlag(NX_BF_KINEMATIC);
        nxActor.putToSleep();
    }
    else
    {
        nxActor.clearBodyFlag(NX_BF_KINEMATIC);
        nxActor.wakeUp();
    }
}

This will disable everything for the actor, collisions, scene queries etc. I use this strategy to preload all actors to the scene and to hide inactive objects. When their turn comes, enable them, disable others. Beware that loading all actors at once may consume the memory.


I'm not familiar with PhysX, but I can make some educated guesses about how it works. Here are one or two ideas that may or may not work depending on, e.g., how PhysX decides to declare an object "resolved":

If the blocks are actually moving, it's probably because there's some imprecision in their initial location, which gives them room to settle. Maybe there's a way to reduce that imprecision, for instance by saving a resolved configuration instead of relying on one designed on paper. Since they eventually stop, there must be a dissipative force at work (e.g. friction), and it must have a parameter. So turn it up high at first, as if the blocks are immersed in honey, then dial it down.

Whether or not they're actually moving, a block at the top of a big jittery tower of blocks can't possibly settle down until all the blocks below it have done so, so all the calculation to simulate its jiggling is completely wasted-- to say nothing of how its uncertainty may disturb the blocks below. So try being a bricklayer, placing the bottom objects first, letting them resolve, then working your way up (in "courses", as they say).

If you can't eliminate it, cover it up; maybe you can hide the blocks for the first few seconds, then raise the curtain once they're resolved. This doesn't make things faster but it might make things more presentable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜