//taken from //http://catlikecoding.com/unity/tutorials/marching-squares/ private void TriangulateCell(int i, MapElement a, MapElement b, MapElement c, MapElement d) { int cellType = GetCellType(a, b, c, d); switch (cellType) { //simple case, no triangle case 0: return; //corner case case 1: AddTriangle((rowCacheMin[i]), (edgeCacheMin), (rowCacheMin[i + 1])); SetVertexHeight(innerHeightCorner, rowCacheMin[i]); SetVertexHeight(outerHeightCorner, edgeCacheMin); SetVertexHeight(outerHeightCorner, rowCacheMin[i + 1]); if (Wall != null) { Wall.AddACAB(WallIndex(i)); } break; case 2: AddTriangle((rowCacheMin[i + 2]), (rowCacheMin[i + 1]), (edgeCacheMax)); SetVertexHeight(innerHeightCorner, rowCacheMin[i + 2]); SetVertexHeight(outerHeightCorner, rowCacheMin[i + 1]); SetVertexHeight(outerHeightCorner, edgeCacheMax); if (Wall != null) { Wall.AddABBD(WallIndex(i)); } break; case 4: AddTriangle((rowCacheMax[i]), (rowCacheMax[i + 1]), (edgeCacheMin)); SetVertexHeight(innerHeightCorner, rowCacheMax[i]); SetVertexHeight(outerHeightCorner, rowCacheMax[i + 1]); SetVertexHeight(outerHeightCorner, edgeCacheMin); if (Wall != null) { Wall.AddCDAC(WallIndex(i)); } break; case 8: AddTriangle((rowCacheMax[i + 2]), (edgeCacheMax), (rowCacheMax[i + 1])); SetVertexHeight(innerHeightCorner, rowCacheMax[i + 2]); SetVertexHeight(outerHeightCorner, edgeCacheMax); SetVertexHeight(outerHeightCorner, rowCacheMax[i + 1]); if (Wall != null) { Wall.AddBDCD(WallIndex(i)); } break; //edge case case 3: AddQuad((rowCacheMin[i]), (edgeCacheMin), (edgeCacheMax), (rowCacheMin[i + 2])); //top edge SetVertexHeight(innerHeightEdge, rowCacheMin[i]); SetVertexHeight(outerHeightEdge, edgeCacheMin); SetVertexHeight(outerHeightEdge, edgeCacheMax); SetVertexHeight(innerHeightEdge, rowCacheMin[i + 2]); if (Wall != null) { Wall.AddACBD(WallIndex(i)); } break; case 5: AddQuad((rowCacheMin[i]), (rowCacheMax[i]), (rowCacheMax[i + 1]), (rowCacheMin[i + 1])); //right edge SetVertexHeight(innerHeightEdge, rowCacheMin[i]); SetVertexHeight(innerHeightEdge, rowCacheMax[i]); SetVertexHeight(outerHeightEdge, rowCacheMax[i + 1]); SetVertexHeight(outerHeightEdge, rowCacheMin[i + 1]); if (Wall != null) { Wall.AddCDAB(WallIndex(i)); } break; case 10: AddQuad((rowCacheMin[i + 1]), (rowCacheMax[i + 1]), (rowCacheMax[i + 2]), (rowCacheMin[i + 2])); //left edge SetVertexHeight(outerHeightEdge, rowCacheMin[i + 1]); SetVertexHeight(outerHeightEdge, rowCacheMax[i + 1]); SetVertexHeight(innerHeightEdge, rowCacheMax[i + 2]); SetVertexHeight(innerHeightEdge, rowCacheMin[i + 2]); if (Wall != null) { Wall.AddABCD(WallIndex(i)); } break; case 12: AddQuad((edgeCacheMin), (rowCacheMax[i]), (rowCacheMax[i + 2]), (edgeCacheMax)); //bottom edge SetVertexHeight(outerHeightEdge, edgeCacheMin); SetVertexHeight(innerHeightEdge, rowCacheMax[i]); SetVertexHeight(innerHeightEdge, rowCacheMax[i + 2]); SetVertexHeight(outerHeightEdge, edgeCacheMax); if (Wall != null) { Wall.AddBDAC(WallIndex(i)); } break; //The cases with three filled and one empty voxel each require a square with a single corner cut away. //This is basically a pentagon that's stretched out of shape. //A pentagon can be created with five vertices and three triangles that form a small fan. case 7: AddPentagon((rowCacheMin[i]), (rowCacheMax[i]), (rowCacheMax[i + 1]), (edgeCacheMax), (rowCacheMin[i + 2])); SetVertexHeight(innerHeight, rowCacheMin[i]); SetVertexHeight(innerHeightEdge, rowCacheMax[i]); SetVertexHeight(outerHeightCorner, rowCacheMax[i + 1]); SetVertexHeight(outerHeightCorner, edgeCacheMax); SetVertexHeight(innerHeightEdge, rowCacheMin[i + 2]); if (Wall != null) { Wall.AddCDBD(WallIndex(i)); } break; case 11: AddPentagon((rowCacheMin[i + 2]), (rowCacheMin[i]), (edgeCacheMin), (rowCacheMax[i + 1]), (rowCacheMax[i + 2])); SetVertexHeight(innerHeight, rowCacheMin[i + 2]); SetVertexHeight(innerHeightEdge, rowCacheMin[i]); SetVertexHeight(outerHeightCorner, edgeCacheMin); SetVertexHeight(outerHeightCorner, rowCacheMax[i + 1]); SetVertexHeight(innerHeightEdge, rowCacheMax[i + 2]); if (Wall != null) { Wall.AddACCD(WallIndex(i)); } break; case 13: AddPentagon((rowCacheMax[i]), (rowCacheMax[i + 2]), (edgeCacheMax), (rowCacheMin[i + 1]), (rowCacheMin[i])); SetVertexHeight(innerHeight, rowCacheMax[i]); SetVertexHeight(innerHeightEdge, rowCacheMax[i + 2]); SetVertexHeight(outerHeightCorner, edgeCacheMax); SetVertexHeight(outerHeightCorner, rowCacheMin[i + 1]); SetVertexHeight(innerHeightEdge, rowCacheMin[i]); if (Wall != null) { Wall.AddBDAB(WallIndex(i)); } break; case 14: AddPentagon((rowCacheMax[i + 2]), (rowCacheMin[i + 2]), (rowCacheMin[i + 1]), (edgeCacheMin), (rowCacheMax[i])); SetVertexHeight(innerHeight, rowCacheMax[i + 2]); SetVertexHeight(innerHeightEdge, rowCacheMin[i + 2]); SetVertexHeight(outerHeightCorner, rowCacheMin[i + 1]); SetVertexHeight(outerHeightCorner, edgeCacheMin); SetVertexHeight(innerHeightEdge, rowCacheMax[i]); if (Wall != null) { Wall.AddABAC(WallIndex(i)); } break; //Only the two opposite-corner cases are still missing, 6 and 9. //I decided to disconnect them, so they require two triangles each, which you can copy from the single-triangle cases. //Connecting them would've required a hexagon instead. case 6: AddTriangle((rowCacheMin[i + 2]), (rowCacheMin[i + 1]), (edgeCacheMax)); AddTriangle((rowCacheMax[i]), (rowCacheMax[i + 1]), (edgeCacheMin)); if (Wall != null) { Wall.AddABBD(WallIndex(i)); } if (Wall != null) { Wall.AddCDAC(WallIndex(i)); } if (Wall != null) { Wall.AddABAC(WallIndex(i)); } if (Wall != null) { Wall.AddCDBD(WallIndex(i)); } break; case 9: AddTriangle((rowCacheMin[i]), (edgeCacheMin), (rowCacheMin[i + 1])); AddTriangle((rowCacheMax[i + 2]), (edgeCacheMax), (rowCacheMax[i + 1])); if (Wall != null) { Wall.AddACAB(WallIndex(i)); } if (Wall != null) { Wall.AddBDCD(WallIndex(i)); } if (Wall != null) { Wall.AddBDAB(WallIndex(i)); } if (Wall != null) { Wall.AddACCD(WallIndex(i)); } break; //center case case 15: AddQuad((rowCacheMin[i]), (rowCacheMax[i]), (rowCacheMax[i + 2]), (rowCacheMin[i + 2])); SetVertexHeight(innerHeight, rowCacheMin[i]); SetVertexHeight(innerHeight, rowCacheMax[i]); SetVertexHeight(innerHeight, rowCacheMax[i + 2]); SetVertexHeight(innerHeight, rowCacheMin[i + 2]); break; } }