Exemplo n.º 1
0
    // Function to check each corner of a given cube - this is the "March" of Marching Cubes
    //      The x,y,z arguments are the positions of nodes in a chunk's node matrix
    //      The currChunk argument is the nodes within the current chunk's matrix data
    ChunkMatrix PolygonizeCube(ChunkMatrix currChunk, int x, int y, int z)
    {
        Node[,,] nodes = currChunk.nodes;

        // get the type of cube dependant on the active vertices within it
        int cubeIndex = MarchingCubes.CheckVertices(currChunk, chunks, surfaceLevel, x, y, z);

        // if there were no active nodes in this cube, break the function
        if (cubeIndex == 0)
        {
            return(currChunk);
        }

        // use the edge table to obtain which edges are active for this cube configuration
        int edges = MarchingCubes.edgeTable[cubeIndex];

        // array holding the positions of each edge vertex
        Vector3[] edgeVertices = emptyVertices;

        // value of which vertex is being worked on at the moment for the mesh creation
        int vert;

        // Find the vertices for the triangles in the cube - TODO: do the interpolation here   *****************************************
        for (int i = 0; i < edgeVertices.Length; i++)      // edge vertices length is the numver of edges in the cube
        {
            if ((edges & (1 << i)) != 0)                   // checks the boolean values from the edges table to see which edges are active
            {
                // start by assuming a hard edge - turn softEdge to false to create a more flat terrain
                float edgeOffset = 1 / (float)cubeResolution / 2f;

                // turning on softEdge will use the linear interpolation to smooth out the edges
                if (softEdge)
                {
                    float[] cube = MarchingCubes.GetIsovaluesOfCube(nodes, x, y, z);
                    edgeOffset = MarchingCubes.CalculateEdgeOffset(cube[MarchingCubes.edgeConnection[i, 0]], cube[MarchingCubes.edgeConnection[i, 1]], surfaceLevel) / (float)cubeResolution;
                }

                // The edgeVertices array holds the position for where the vertex will be drawn along the edge
                //      To figure this out, we need the position of the current node added to the
                //          VertexOffset defined by the LUT that shows where the next edge is in comparison to this current one
                //          The vertex offset needs to be divided by the cube resolution because the distance between edges will change if there are more cubes in the same amount of space
                //          The edgeOffset is the linear interpolated value we found and it is basically a percentage of how far between the current and next node that the vertex should be placed
                //          The edgeOffset needs to be multiplied by the edgeDirection value in order to know which direction that the offset is in

                edgeVertices[i].x = nodes[x, y, z].position.x + MarchingCubes.vertexOffset[MarchingCubes.edgeConnection[i, 0], 0] / (float)cubeResolution + edgeOffset * MarchingCubes.edgeDirection[i, 0];
                edgeVertices[i].y = nodes[x, y, z].position.y + MarchingCubes.vertexOffset[MarchingCubes.edgeConnection[i, 0], 1] / (float)cubeResolution + edgeOffset * MarchingCubes.edgeDirection[i, 1];
                edgeVertices[i].z = nodes[x, y, z].position.z + MarchingCubes.vertexOffset[MarchingCubes.edgeConnection[i, 0], 2] / (float)cubeResolution + edgeOffset * MarchingCubes.edgeDirection[i, 2];
            }
        }

        // Create the triangles from these verts - there will be at most 5 triangles to be made per cube
        for (int i = 0; i < 5; i++)
        {
            if (MarchingCubes.triTable[cubeIndex, 3 * i] < 0)       // no triangles to be made
            {
                break;
            }

            // get the current number of verts in the mesh
            int vertexCount = currChunk.vertices.Count;


            for (int j = 0; j < 3; j++)                             // iterate through the triangle verts
            {
                vert = MarchingCubes.triTable[cubeIndex, 3 * i + j];
                currChunk.indices.Add(vertexCount + windingOrder[j]);
                currChunk.vertices.Add(edgeVertices[vert]);
            }
        }


        return(currChunk);
    }