Пример #1
0
    /// Generate the visible triangles for a grid cell with the Marching Cubes Algorithm
    public List <Triangle> GenerateTriangles(float isolevel, Gridcell grid)
    {
        // Create a list to store the triangles we will return
        List <Triangle> returnTriangles = new List <Triangle>();

        int cubeIndex = 0;

        if (grid.val[0] < isolevel)
        {
            cubeIndex += 1;
        }
        if (grid.val[1] < isolevel)
        {
            cubeIndex += 2;
        }
        if (grid.val[2] < isolevel)
        {
            cubeIndex += 4;
        }
        if (grid.val[3] < isolevel)
        {
            cubeIndex += 8;
        }
        if (grid.val[4] < isolevel)
        {
            cubeIndex += 16;
        }
        if (grid.val[5] < isolevel)
        {
            cubeIndex += 32;
        }
        if (grid.val[6] < isolevel)
        {
            cubeIndex += 64;
        }
        if (grid.val[7] < isolevel)
        {
            cubeIndex += 128;
        }

        if (cubeIndex == 0 || cubeIndex == 255)
        {
            return(returnTriangles);
        }

        Vector3[] vertlist = new Vector3[12];
        if (IsBitSet(edgeTable[cubeIndex], 1))
        {
            vertlist[0] = VertexInterp(isolevel, grid.p[0], grid.p[1], grid.val[0], grid.val[1]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 2))
        {
            vertlist[1] = VertexInterp(isolevel, grid.p[1], grid.p[2], grid.val[1], grid.val[2]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 4))
        {
            vertlist[2] = VertexInterp(isolevel, grid.p[2], grid.p[3], grid.val[2], grid.val[3]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 8))
        {
            vertlist[3] = VertexInterp(isolevel, grid.p[3], grid.p[0], grid.val[3], grid.val[0]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 16))
        {
            vertlist[4] = VertexInterp(isolevel, grid.p[4], grid.p[5], grid.val[4], grid.val[5]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 32))
        {
            vertlist[5] = VertexInterp(isolevel, grid.p[5], grid.p[6], grid.val[5], grid.val[6]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 64))
        {
            vertlist[6] = VertexInterp(isolevel, grid.p[6], grid.p[7], grid.val[6], grid.val[7]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 128))
        {
            vertlist[7] = VertexInterp(isolevel, grid.p[7], grid.p[4], grid.val[7], grid.val[4]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 256))
        {
            vertlist[8] = VertexInterp(isolevel, grid.p[0], grid.p[4], grid.val[0], grid.val[4]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 512))
        {
            vertlist[9] = VertexInterp(isolevel, grid.p[1], grid.p[5], grid.val[1], grid.val[5]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 1024))
        {
            vertlist[10] = VertexInterp(isolevel, grid.p[2], grid.p[6], grid.val[2], grid.val[6]);
        }
        if (IsBitSet(edgeTable[cubeIndex], 2048))
        {
            vertlist[11] = VertexInterp(isolevel, grid.p[3], grid.p[7], grid.val[3], grid.val[7]);
        }

        for (int i = 0; triTable[cubeIndex][i] != -1; i += 3)
        {
            returnTriangles.Add(new Triangle(vertlist[triTable[cubeIndex][i]], vertlist[triTable[cubeIndex][i + 1]], vertlist[triTable[cubeIndex][i + 2]]));
        }

        /*for (int p = 0; p < returnTriangles.Count; p++)
         *      Debug.Log("v1: " + returnTriangles[p].pointOne.ToString() + ", v2: " +
         *                returnTriangles[p].pointTwo.ToString() + ", v3: " +
         *                returnTriangles[p].pointThree.ToString());
         * Debug.Log("______________________");*/

        return(returnTriangles);
    }
Пример #2
0
    Mesh GenerateMesh(float[,,] voxels)
    {
        var grids       = new NativeList <Gridcell>(Allocator.TempJob);
        var gridOffsets = new NativeList <Vector3Int>(Allocator.TempJob);

        for (int x = 0; x < dimensions.x - 1; x++)
        {
            for (int y = 0; y < dimensions.y; y++)
            {
                for (int z = 0; z < dimensions.z - 1; z++)
                {
                    Gridcell gridcell;

                    try
                    {
                        gridcell = new Gridcell
                        {
                            val1 = voxels[x, y, z],
                            val2 = voxels[x, y, 1 + z],
                            val3 = voxels[1 + x, y, 1 + z],
                            val4 = voxels[1 + x, y, z],
                            val5 = voxels[x, 1 + y, z],
                            val6 = voxels[x, 1 + y, 1 + z],
                            val7 = voxels[1 + x, 1 + y, 1 + z],
                            val8 = voxels[1 + x, 1 + y, z],
                        };
                    }

                    catch
                    {
                        gridcell = new Gridcell
                        {
                            val1 = voxels[x, y, z],
                            val2 = voxels[x, y, 1 + z],
                            val3 = voxels[1 + x, y, 1 + z],
                            val4 = voxels[1 + x, y, z],
                            val5 = 0,
                            val6 = 0,
                            val7 = 0,
                            val8 = 0,
                        };
                    }

                    if (gridcell.Equals(Gridcell.one) || gridcell.Equals(Gridcell.zero))
                    {
                        continue;
                    }

                    int index = x + dimensions.y * (y + (dimensions.z - 1) * z);

                    grids.Add(gridcell);
                    gridOffsets.Add(new Vector3Int(x, y, z));
                }
            }
        }

        var trianglesMC = new NativeQueue <Triangle>(Allocator.Persistent);

        new PolygoniseJob()
        {
            grids       = grids,
            gridOffsets = gridOffsets,
            isolevel    = isolevel,

            trianglesMC = trianglesMC,
        }.Schedule(grids.Length, 64).Complete();

        grids.Dispose();
        gridOffsets.Dispose();

        Dictionary <Vector3, int> vertexDictionary = new Dictionary <Vector3, int>(Vec3EqComparer.c);
        NativeList <int>          triangles        = new NativeList <int>(Allocator.TempJob);

        while (trianglesMC.TryDequeue(out Triangle triangle))
        {
            foreach (Vector3 vertex in triangle.Verts)
            {
                if (!vertexDictionary.TryGetValue(vertex, out int vertexIndex))
                {
                    vertexIndex = vertexDictionary.Count;
                    vertexDictionary.Add(vertex, vertexIndex);
                }

                triangles.Add(vertexIndex);
            }
        }

        var vertices = new NativeArray <Vector3>(vertexDictionary.Keys.ToArray(), Allocator.TempJob);

        trianglesMC.Dispose();

        var uv = new NativeArray <Vector2>(vertices.Length, Allocator.TempJob);

        new GetUVJob()
        {
            verts      = vertices,
            uv         = uv,
            dimensions = dimensions,
        }.Schedule(uv.Length, 64).Complete();

        Mesh terrainMesh = new Mesh
        {
            name      = "Terrain" + System.DateTime.UtcNow.ToFileTime().ToString() + " Mesh",
            vertices  = vertices.ToArray(),
            triangles = triangles.ToArray(),
            uv        = uv.ToArray(),
        };

        vertices.Dispose();
        triangles.Dispose();
        uv.Dispose();

        terrainMesh.RecalculateBounds();
        terrainMesh.RecalculateTangents();
        terrainMesh.RecalculateNormals();

        AssetDatabase.CreateAsset(terrainMesh, "Assets/Terrain Data/" + terrainMesh.name + ".asset");
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        return((Mesh)AssetDatabase.LoadAssetAtPath("Assets/Terrain Data/" + terrainMesh.name + ".asset", typeof(Mesh)));
    }