Пример #1
0
        public static void GenerateChunkInterior(List <Vector3> vertices, List <int> triangles, sbyte[][][][] data, int res)
        {
            for (int x = 2; x < res - 2; x++)
            {
                for (int y = 2; y < res - 2; y++)
                {
                    for (int z = 2; z < res - 2; z++)
                    {
                        Util.GridCell cell = new Util.GridCell();
                        cell.points = new Util.Point[8];

                        for (int i = 0; i < 8; i++)
                        {
                            Vector3Int offset  = new Vector3Int((int)Tables.CellOffsets[i].x, (int)Tables.CellOffsets[i].y, (int)Tables.CellOffsets[i].z) + new Vector3Int(x, y, z);
                            sbyte      density = data[(int)offset.x][offset.y][offset.z][0];
                            cell.points[i].density  = density;
                            cell.points[i].position = offset;
                        }

                        GenerateRegularCell(cell, vertices, triangles, 0);
                    }
                }
            }
        }
Пример #2
0
        public static void GenerateRegularCell(Util.GridCell cell, List <Vector3> vertices, List <int> triangles, float isovalue)
        {
            Vector3[] vertlist = new Vector3[12];

            int i, ntriang;
            int cubeindex;

            cubeindex = 0;
            if (cell.points[0].density < isovalue)
            {
                cubeindex |= 1;
            }
            if (cell.points[1].density < isovalue)
            {
                cubeindex |= 2;
            }
            if (cell.points[2].density < isovalue)
            {
                cubeindex |= 4;
            }
            if (cell.points[3].density < isovalue)
            {
                cubeindex |= 8;
            }
            if (cell.points[4].density < isovalue)
            {
                cubeindex |= 16;
            }
            if (cell.points[5].density < isovalue)
            {
                cubeindex |= 32;
            }
            if (cell.points[6].density < isovalue)
            {
                cubeindex |= 64;
            }
            if (cell.points[7].density < isovalue)
            {
                cubeindex |= 128;
            }

            /* Cube is entirely in/out of the surface */
            if (Tables.edgeTable[cubeindex] == 0)
            {
                return;
            }

            /* Find the vertices where the surface intersects the cube */
            if ((Tables.edgeTable[cubeindex] & 1) == 1)
            {
                vertlist[0] = UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]);
            }
            if ((Tables.edgeTable[cubeindex] & 2) == 2)
            {
                vertlist[1] = UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]);
            }
            if ((Tables.edgeTable[cubeindex] & 4) == 4)
            {
                vertlist[2] = UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]);
            }
            if ((Tables.edgeTable[cubeindex] & 8) == 8)
            {
                vertlist[3] = UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]);
            }
            if ((Tables.edgeTable[cubeindex] & 16) == 16)
            {
                vertlist[4] = UtilFuncs.Lerp(isovalue, cell.points[4], cell.points[5]);
            }
            if ((Tables.edgeTable[cubeindex] & 32) == 32)
            {
                vertlist[5] = UtilFuncs.Lerp(isovalue, cell.points[5], cell.points[6]);
            }
            if ((Tables.edgeTable[cubeindex] & 64) == 64)
            {
                vertlist[6] = UtilFuncs.Lerp(isovalue, cell.points[6], cell.points[7]);
            }
            if ((Tables.edgeTable[cubeindex] & 128) == 128)
            {
                vertlist[7] = UtilFuncs.Lerp(isovalue, cell.points[7], cell.points[4]);
            }
            if ((Tables.edgeTable[cubeindex] & 256) == 256)
            {
                vertlist[8] = UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[4]);
            }
            if ((Tables.edgeTable[cubeindex] & 512) == 512)
            {
                vertlist[9] = UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[5]);
            }
            if ((Tables.edgeTable[cubeindex] & 1024) == 1024)
            {
                vertlist[10] = UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[6]);
            }
            if ((Tables.edgeTable[cubeindex] & 2048) == 2048)
            {
                vertlist[11] = UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[7]);
            }

            /* Create the triangle */

            ntriang = 0;
            for (i = 0; Tables.triTable[cubeindex][i] != -1; i += 3)
            {
                ntriang++;
            }
            for (i = 0; Tables.triTable[cubeindex][i] != -1; i++)
            {
                triangles.Add(vertices.Count);
                vertices.Add(vertlist[Tables.triTable[cubeindex][i]]);
            }
        }
Пример #3
0
        public static void GenerateChunkExterior(List <Vector3> vertices, List <int> triangles, sbyte[][][][] data, byte chunkLod, int res)
        {
            int rm2 = res - 2;
            int rm4 = res - 4;

            for (int x = 0; x < res; x += 2)
            {
                for (int y = 0; y < res; y += 2)
                {
                    for (int z = 0; z < res; z += 2)
                    {
                        bool isMinimal = x == 0 || y == 0 || z == 0;
                        bool isMaximal = x == rm2 || y == rm2 || z == rm2;
                        if (!isMinimal && !isMaximal)
                        {
                            continue;
                        }

                        byte cellLod = 0;
                        if (x == 0)
                        {
                            cellLod |= 1;
                        }
                        if (x == rm2)
                        {
                            cellLod |= 2;
                        }
                        if (y == 0)
                        {
                            cellLod |= 4;
                        }
                        if (y == rm2)
                        {
                            cellLod |= 8;
                        }
                        if (z == 0)
                        {
                            cellLod |= 16;
                        }
                        if (z == rm2)
                        {
                            cellLod |= 32;
                        }
                        cellLod = (byte)(cellLod & chunkLod);

                        byte cellLod2 = 0;
                        if (x == 2)
                        {
                            cellLod2 |= 1;
                        }
                        if (x == rm4)
                        {
                            cellLod2 |= 2;
                        }
                        if (y == 2)
                        {
                            cellLod2 |= 4;
                        }
                        if (y == rm4)
                        {
                            cellLod2 |= 8;
                        }
                        if (z == 2)
                        {
                            cellLod2 |= 16;
                        }
                        if (z == rm4)
                        {
                            cellLod2 |= 32;
                        }
                        cellLod2 = (byte)(cellLod2 & chunkLod);

                        int iPos    = -1;
                        int numOnes = 0;
                        for (int i = 0; i < 6; i++)
                        {
                            if (((cellLod >> i) & 1) == 1)
                            {
                                numOnes++;
                                iPos = i;
                            }
                        }

                        if (numOnes == 1)
                        {
                            GenerateTransitionCell(new Vector3Int(x, y, z), vertices, triangles, cellLod2, data, tvCellRotations[iPos]);
                        }
                        else
                        {
                            Util.GridCell cell = new Util.GridCell();
                            cell.points = new Util.Point[8];
                            for (int i = 0; i < 8; i++)
                            {
                                Vector3Int offset  = (new Vector3Int((int)Tables.CellOffsets[i].x, (int)Tables.CellOffsets[i].y, (int)Tables.CellOffsets[i].z)) * 2 + new Vector3Int(x, y, z);
                                sbyte      density = data[(int)offset.x][offset.y][offset.z][0];
                                cell.points[i].density  = density;
                                cell.points[i].position = offset;
                            }
                            GenerateRegularCell(cell, vertices, triangles, 0);
                        }
                    }
                }
            }
        }
Пример #4
0
        public static void PolyganiseTetrahedron(Util.GridCell cell, List <Vector3> vertices, float isovalue)
        {
            int triangleIndex = 0;

            if (cell.points[0].density < isovalue)
            {
                triangleIndex |= 1;
            }
            if (cell.points[1].density < isovalue)
            {
                triangleIndex |= 2;
            }
            if (cell.points[2].density < isovalue)
            {
                triangleIndex |= 4;
            }
            if (cell.points[3].density < isovalue)
            {
                triangleIndex |= 8;
            }

            // these cases were taken from https://github.com/Calvin-L/MarchingTetrahedrons/blob/master/Decimate.cpp
            switch (triangleIndex)
            {
            case 0:
            case 15:
                break;

            case 0x01:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                break;

            case 0x02:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                break;

            case 0x04:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1]));
                break;

            case 0x08:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                break;

            case 0x03:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                break;

            case 0x05:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]));
                break;

            case 0x09:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                break;

            case 0x06:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2]));
                break;

            case 0x0C:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1]));
                break;

            case 0x0A:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                break;

            case 0x07:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[1]));
                break;

            case 0x0B:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0]));
                break;

            case 0x0D:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]));
                break;

            case 0x0E:
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2]));
                vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[3]));
                break;
            }
        }