Search code examples
c#unity-game-enginemeshtriangulation

marching cubes drawing triangles unity


I am trying to implement marching cubes into my game, and so far I have set up a system for drawing triangles with four points in world space. I have got the system working where I set the points, but then when I draw the two triangles to make it a mesh, it only draws one, but I set up a print() statement, and it shows that 2 triangles are drawn each time, so that is normal. I can't figure out what I need to do. Here is my code, and comment on this post if you need any more pics/code:

    private void Triangulate()
    {
        vertices.Clear();
        triangles.Clear();
        mesh.Clear();

        TriangulateCellRows();
        print(triangles.Count);
        mesh.vertices = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
    }
    private void TriangulateCellRows()
    {
        int cells = resolution - 1; int heightCells = heightRes - 1;
        for (int i = 0, y = 0; y < heightCells; y++)
        {
            for (int x = 0; x < cells; x++, i++)
            {
                for (int z = 0; z < cells; z++, i++)
                {
                    TriangulateCell(
                        voxels[i],
                        voxels[i + 1],
                        voxels[i + resolution],
                        voxels[i + resolution + 1],
                        voxels[i + resolution * resolution],
                        voxels[i + resolution * resolution + 1],
                        voxels[i + resolution * resolution + resolution],
                        voxels[i + resolution * resolution + resolution + 1]);
                }
            }
        }
    }
    private void TriangulateCell(Voxel a, Voxel b, Voxel c, Voxel d, Voxel e, Voxel f, Voxel g, Voxel h)
    {
        int cellType = 0;
        if (a.state)
        {
            cellType |= 1;
        }
        if (b.state)
        {
            cellType |= 2;
        }
        if (c.state)
        {
            cellType |= 4;
        }
        if (d.state)
        {
            cellType |= 8;
        }
        if (e.state)
        {
            cellType |= 16;
        }
        if (f.state)
        {
            cellType |= 32;
        }
        if (g.state)
        {
            cellType |= 64;
        }
        if (h.state)
        {
            cellType |= 128;
        }
        switch (cellType)
        {
            case 0:
                return;/*
            case 1:
                AddTriangle(a.xEdgePosition, b.yEdgePosition, c.zEdgePosition);
                break;*/
            case 15:
                AddQuad(a.yEdgePosition, b.yEdgePosition, c.yEdgePosition, d.yEdgePosition);
                print(a.yEdgePosition + "- " + b.yEdgePosition + "- " + c.yEdgePosition + "- " + d.yEdgePosition);
                print(a.position + "/ " + b.position + "/ " + c.position + "/ " + d.position);
                break;
        }
    }
...
    private void AddQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
    {
        int vertCount = vertices.Count;
        vertices.Add(a);
        vertices.Add(b);
        vertices.Add(c);
        vertices.Add(d);
        triangles.Add(vertCount);
        triangles.Add(vertCount + 1);
        triangles.Add(vertCount + 2);
        triangles.Add(vertCount + 1);
        triangles.Add(vertCount + 2);
        triangles.Add(vertCount + 3);
        print(triangles.Count);
    }

Solution

  • I'm pretty sure your issue here is order.

    Unity uses a clockwise winding order. This means that

    • if you provide the triangles in clockwise order the normal will face towards you and you will see the triangle.

      enter image description here

    • if you provide the triangle in counter-clockwise order the normal will face away from you and you will not see the triangle.

      enter image description here


    Now looking at your code (at least as far as I can tell) your vertices look somewhat like

    C--D
    |\ |
    | \|
    A--B
    

    and your triangles are A-B-C and B-C-D.

    So as you can see one of them is counter-clockwise (A-B-C), the other one is clockwise (B-C-D)!

    So depending from which side you are looking on these you will either see one or the other but never both at the same time.


    You either rather want

    triangles.Add(vertCount);
    triangles.Add(vertCount + 2);
    triangles.Add(vertCount + 1);
    
    triangles.Add(vertCount + 1);
    triangles.Add(vertCount + 2);
    triangles.Add(vertCount + 3);
    

    or

    triangles.Add(vertCount);
    triangles.Add(vertCount + 1);
    triangles.Add(vertCount + 2);
    
    triangles.Add(vertCount + 1);
    triangles.Add(vertCount + 3);
    triangles.Add(vertCount + 2);
    

    depending on your needs and in which direction the resulting triangles should face