瞬间睡觉堆栈的动态对象

时间:2010-08-26 13:46:25

标签: physics game-physics physx

我的场景有很多动态对象。当模拟开始时,它们需要一段时间才能在它们成为沉睡岛之前“解决”。这会在最初几秒内显着影响性能。

是否有安排堆叠的技术让它们立即睡觉?

我正在使用PhysX。

2 个答案:

答案 0 :(得分:1)

您可以使用

NxActor::putToSleep();

启动时。这将大大提高场景性能。但是,如果你的堆栈上有错位的对象(即一个飞行的立方体),它将不会掉落,直到另一个动态物体撞击它。

这种方法似乎不适用于主动移动的对象。例如,如果我的动态对象在我的场景中以5m / s的速度移动并且如果我试图强制它进入睡眠状态,则putToSleep将无法工作(即使我首先将对象的速度设置为0,然后将其设置为0睡眠)

如果你需要强制睡眠并禁用动态角色,这是一个解决方法。

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();
    }
}

这将禁用actor,碰撞,场景查询等的所有内容。我使用此策略将所有actor预加载到场景中并隐藏非活动对象。轮到他们时,启用它们,禁用其他人。请注意,一次加载所有演员可能会消耗内存。

答案 1 :(得分:0)

我不熟悉PhysX,但我可以对它的工作原理做一些有根据的猜测。这里有一两个想法可能会或可能不会取决于,例如,PhysX如何决定声明对象“已解决”:

如果块实际上正在移动,可能是因为它们的初始位置存在一些不精确,这使它们有足够的空间来定居。也许有办法减少这种不精确性,例如通过保存已解析的配置而不是依赖于纸上设计的配置。由于它们最终停止,因此必须存在耗散力(例如摩擦力),并且必须具有参数。因此,首先将它调高,好像块浸在蜂蜜中,然后将其拨下来。

无论他们是否真的在移动,在一个巨大的紧张的塔楼顶部的一个街区不可能安定下来,直到它下面的所有街区都这样做,所以模拟其摇晃的所有计算都是完全的浪费 - 更不用说它的不确定性如何会扰乱下面的街区。因此,尝试成为一个瓦工,将底部物体放在第一位,让他们解决,然后按照自己的方式工作(在“课程”中,如他们所说)。

如果你无法消除它,请掩盖它;也许你可以在最初的几秒钟内隐藏这些积木,然后在它们解决后抬起帷幕。这不会让事情变得更快,但它可能使事情变得更容易。