0

我正在尝试正确排序我的可渲染对象/演员,并注意到我在墙壁上遇到了一些问题,因为它们是按中心点排序的。因此,我在绘制所有演员之前,根据他们与相机的距离,使用插入排序对他们进行排序。在那之后,我试图确定墙应该画在比赛场地的后面还是前面。为了解释这一点,游戏发生在一个由 6 个平面组成的立方体内。因为我可以围绕那个立方体旋转相机,所以我需要一个排序,根据这个排序将飞机放在前面/后面。所以这是一张图片,所以你知道我们在说什么:

在此处输入图像描述

你可以清楚地看到在那种蛇的前面发生了什么。

好的,这是我目前的排序:

//list of Actors the abstract class which Wall and cube and so on extend
void Group::insertionSort(vector<Actor *> &actors)
{
    int j;

    for (int i = 1; i < actors.size(); i++)
    {
        Actor *val = actors[i];
        j = i - 1;

        while (j >= 0 && distanceToCamera(*actors[j]) < distanceToCamera(*val))
        {
            actors[j + 1] = actors[j];
            j = j - 1;
        }
        actors[j + 1] = val;
    }
}

float Group::distanceToCamera(Actor &a)
{
    float result = 0;
    XMVECTOR posActor = XMLoadFloat3(&a.getPosition()); //here i get the centerpoint of the object
    XMVECTOR posCamera = XMLoadFloat3(&m_camera->getPosition());
    XMVECTOR length = XMVector3Length(posCamera - posActor);
    XMStoreFloat(&result, length);
    return result;
}

为了确定它是否是Wall我使用的这种类型,dynamic_cast<Wall*>(val)但我没有将它们放在矢量的前面/后面,这取决于它。要记住对象返回它们的中心点。谁能引导我走向正确的道路?

4

1 回答 1

1

很难回答您的问题,因为它是一个复杂的系统,您在此处尚未完全解释,并且您还应该在发布之前将其简化为更简单的东西。您很有可能会在途中找到解决办法。无论如何,我会做一些猜测......

现在,我要解决的第一件事是排序算法。如果不深入分析它是否在所有情况下都能正常工作,我会把它扔掉并使用 std::sort(),它既高效又不太可能包含错误。

在替换它时,您需要仔细考虑两个渲染对象之间的顺序:问题是什么时候需要在另一个对象之前绘制一个对象?您正在使用中心点到相机的距离。我不确定您是在对 2D 对象还是 3D 对象进行排序,但在这两种情况下,很容易找到这样不起作用的示例!例如,一个不直接面向相机的大方块可能会覆盖一个较小的方块,即使较小方块的中心更近。另一个问题是当两个对象相交时。同样对于 3D 对象,如果它们具有不同的大小或相交,那么您的算法将不起作用。如果您的对象都具有相同的大小并且它们不能相交,那么您应该没问题。

不过,在这里我怀疑一个问题,可能是物体的表面和立方体网格的表面具有完全相同的位置。一种方法是稍微缩小对象或扩大外部网格,以使顺序始终清晰。这也可以解决您遭受浮点舍入错误的问题。由于这些原因,两个在数学上没有顺序的对象可能会根据情况最终处于不同的位置。这可以表现为它们根据相机角度在可见到覆盖之间闪烁。

最后一件事:我假设您出于教育原因想自己解决这个问题,对吧?否则,使用现有的渲染工具包将完全浪费时间,甚至会将所有计算卸载到图形硬件上。

于 2014-05-25T10:34:37.450 回答