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);
}
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.
if you provide the triangle in counter-clockwise order the normal will face away from you and you will not see the triangle.
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