创建一个统一的平面,三角形看起来不对

时间:2014-02-19 15:47:05

标签: c# unity3d

我正在使用C#创建一架飞机,我已经让它“工作”我得到了一架飞机。然而,三角形似乎没有正确连接,我无法理解为什么。

正如你所看到的那样,它比我能更好地解释它。

我认为这个问题只与我的指数有关,但我不确定。

我认为也可能有一个三角形不存在,所以我认为我的阵列也因为某些原因而变小。

Mesh CreatePlane(int width, int depth)
{
    Mesh m = new Mesh();
    int numVert=(width+1)*(depth+1);
    Vector3[] vertecies = new Vector3[numVert];
    Vector2[] uvs = new Vector2[numVert];
    int[] triangles = new int[width*depth*6];

    float uvx = 1.0f/width;
    float uvy = 1.0f/depth;
    int index = 0;


    for (int i = 0;i<width;i++)
    {
        for(int j = 0;j<depth;j++)
        {
            vertecies[index] = new Vector3(i,0,-j);
            uvs[index++] = new Vector2(j*uvx,i*uvy);

        }
    }

    index = 0;
    for(int j=0; j<depth; j++)
    {
        for(int i=0; i<width; i++)
        {

            triangles[index++] = (j * (width+1)) + i;
            triangles[index++] = ((j+1) * (width+1)) + i;
            triangles[index++] = (j * (width+1)) + i + 1;

            triangles[index++] = ((j+1) * (width+1)) + i;
            triangles[index++] = ((j+1) * (width+1)) + i + 1;
            triangles[index++] = (j * (width+1)) + i + 1;

        }
    }

    m.name = "ScriptPlane";
    m.vertices = vertecies;
    m.uv = uvs;
    m.triangles = triangles;
    m.RecalculateNormals();

    return m;
}

2 个答案:

答案 0 :(得分:4)

您以这种方式计算uvx

float uvx = 1.0f/width;

然后你以这种方式循环宽度:

for (int i = 0;i<width;i++)
{
    for(int j = 0;j<depth;j++)
    {
        vertecies[index] = new Vector3(i,0,-j);
        uvs[index++] = new Vector2(j*uvx,i*uvy);
    }
}

如果你近距离看,有2个错误:

  • j乘以uvx,但它从0depth周期(不应该是width?);
  • 您需要循环至widthdepth包括(使用<= width< width + 1)。

这些只是UV坐标,不要将顶点保留在该循环中。它不会解决你的问题,而只是你稍后会注意到的那两个错误。

要解决三角问题,请尝试以下方法:

0 +--+ 2     + 2
  | /       /|
  |/       / |
1 +     1 +--+ 3

0 -> 1 -> 2
2 -> 1 -> 3

重要的是,逆时针方向订购它们以使背面剔除正常工作。 您可以使用任何其他顺序,有一些非常聪明的解决方案可以切换对角线并保持相邻性,这是优化网格缓冲区的旧硬件所必需的。较新的硬件将动态执行这些优化,而不需要您进行数学运算。

如上图所示,在三角形缓冲区中对三角形进行排序:

b = (j * width + i) * 6;
triangles[index++] = b + 0;
triangles[index++] = b + 1;
triangles[index++] = b + 2;

triangles[index++] = b + 2;
triangles[index++] = b + 1;
triangles[index++] = b + 3;

此时,您所要做的就是正确定位顶点。你发布了这个:

vertecies[index] = new Vector3(i,0,-j);

相反,你应该在一个单独的循环中

bx = i;
by = -j;
vertecies[index++] = new Vector3(bx + 0, 0, by - 1); // 0
vertecies[index++] = new Vector3(bx + 0, 0, by - 0); // 1
vertecies[index++] = new Vector3(bx + 1, 0, by - 1); // 2
vertecies[index++] = new Vector3(bx + 1, 0, by - 0); // 3

我也看到你交换yz,这会引起头痛。此外,您将j相对于世界空间坐标的方向反转。

我建议你重新考虑一下,正确定位相机并采用标准的坐标标记方式。它将在以后简化对空间的思考。

如果相机看起来像-Z那么顶点应该用这种方式计算,而不是:

vertecies[index++] = new Vector3(bx + 0, by + 0, 0); // 0
vertecies[index++] = new Vector3(bx + 0, by + 1, 0); // 1
vertecies[index++] = new Vector3(bx + 1, by + 0, 0); // 2
vertecies[index++] = new Vector3(bx + 1, by + 1, 0); // 3

请注意:这不是简单的代码。轻微错误(某些+-符号或某处遗失+1/-1)的可能性很大,您应该相应地纠正错误。这一切应该可以让您更好地了解问题,但最终您必须运行并调试它,直到它正常工作。

答案 1 :(得分:1)

我建议尽可能尝试使用Unity的内置函数,但是如果这对你不起作用,这个脚本应该做你需要的而不需要额外的努力:http://wiki.unity3d.com/index.php?title=CreatePlane&oldid=10448。< / p>

如果您想坚持使用代码,上面的答案将涵盖您发布的代码的问题。