1

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

有没有安排堆叠让他们立即入睡的技术?

我正在使用 PhysX。

4

2 回答 2

1

您可以使用

NxActor::putToSleep();

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

这种方法似乎不适用于主动移动的物体。例如,如果我的动态对象在我的场景中以 5m/s 的速度移动,并且如果我试图强制它进入睡眠状态,putToSleep 将不起作用(即使我先将对象的速度设置为 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();
    }
}

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

于 2011-03-09T20:40:35.613 回答
0

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

如果这些块实际上是在移动,那可能是因为它们的初始位置有些不精确,这给了它们安定的空间。也许有一种方法可以减少这种不精确性,例如通过保存已解决的配置而不是依赖于纸上设计的配置。由于它们最终会停止,因此必须有一个耗散力在起作用(例如摩擦力),并且它必须有一个参数。所以一开始调高,就好像积木浸在蜂蜜里一样,然后调低。

不管它们是否真的在移动,在一个巨大的抖动塔顶部的一个块不可能稳定下来,直到它下面的所有块都这样做了,所以所有模拟它的抖动的计算都完全浪费了——更不用说它的不确定性如何扰乱下面的街区。所以试着做一个砌砖工,首先放置底部的物体,让它们解决,然后按照自己的方式向上工作(正如他们所说的那样,在“课程”中)。

如果不能消除,就掩盖;也许您可以在最初的几秒钟内隐藏块,然后在它们解决后拉开帷幕。这不会让事情变得更快,但它可能会让事情变得更漂亮。

于 2010-08-26T21:12:56.607 回答