Пример #1
0
        //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;
            }
        }