0
\$\begingroup\$

I am trying to do a simple script to generate a plane from a script by creating a new mesh. After trying it, it seems like some of the triangles aren't showing up. I checked if they were in the list by making it publci and they are in it, so I dont understand why the last triangles aren't showing while the others are.

int size = 4;
Mesh meshy;
public List<Vector3> vert = new List<Vector3>();
public List<Vector2> uv = new List<Vector2>();
public List<int> tri = new List<int>();
void Start()
{
    vert = new List<Vector3>();
    tri = new List<int>();
    meshy = new Mesh();
    for (int x = 0; x < size; x++)
    {
        for(int z = 0; z < size; z++)
        {
            vert.Add(new Vector3(x, 0, z));
        }
    }
    meshy.vertices = vert.ToArray();
    for (int i = 0; i < ((size-1)*(size-1));i++)
    {
        tri.Add(i);
        tri.Add(i+1);
        tri.Add(i+size);
        tri.Add(i + size +1);
        tri.Add(i + 1 +(size - 1));
        tri.Add(i + 1);
    }
    meshy.triangles = tri.ToArray();
    for(int i = 0; i < ((size - 1) * (size - 1)); i++)
    {
        uv.Add(new Vector2(0, 0));
        uv.Add(new Vector2(1, 0));
        uv.Add(new Vector2(0, 1));
        uv.Add(new Vector2(1, 1));
    }
    meshy.uv = uv.ToArray();
    GetComponent<MeshFilter>().mesh = meshy;
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I find it often helps to jot down on paper a small version of the problem you're trying to solve, say size = 3 so you have just 3x3 vertices, and pretend to be the CPU, working through the set of instructions you've given it one by one.

First we generate the vertices, running up the z columns then across the x rows:

Numbered vertices

The first iteration of your triangles loop tries to join...

    // In red
    tri.Add(i);                  // 0
    tri.Add(i+1);                // 1
    tri.Add(i+size);             // 3

    // In orange
    tri.Add(i + size +1);        // 4
    tri.Add(i + 1 +(size - 1));  // 3
    tri.Add(i + 1);              // 1

Then we can just add one to these numbers for each of the following iterations. The second iteration joins 1 2 4 (yellow) and 5 4 2 (green). Then the third iteration joins 2 3 5 (blue) and 6 5 3 (purple)... uh oh.

Bad triangle

We made a bogus pair of triangles joining the first column to the second column. But our loop condition says we're only allowed to loop (size - 1) * (size - 1) = 2 * 2 = 4 times, so if we run this code to completion we stop at i = 4, before we've drawn the final quad worth of triangles.

Final state

Your code gets confused when it hits the end of a column, because the way you've written your loop it's no longer aware of the row-column structure of your vertices. Let's fix that.

for(int x = 0; x < size - 1; x++) {
    for(int z = 0; z < size - 1; z++) {
         // Index of the bottom-left vertex in this quad.
         int i = size * x + z;

         // Bottom-left triangle.
         tri.Add(i);
         tri.Add(i + 1);
         tri.Add(i + size);

         // Upper-right triangle.
         tri.Add(i + size + 1);
         tri.Add(i + size);
         tri.Add(i + 1);
    }
}

Now we loop over only those vertices that are the bottom-left corner of some quad in our mesh (0, 1, 3, 4 in this example), and skip creating bogus triangles using vertex 2 as our start point, since it's at the end of a column, on the open edge of the mesh.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you so much!!! that really is the best answer I could have wished for \$\endgroup\$ Oct 4, 2020 at 22:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .