Exemplo n.º 1
0
    public static MeshDetails BuildMesh(float[,] noiseArea, int lod, AreaDetails areaDetails)
    {
        int lodIncrement    = lod == 0 ? 1 : lod * 2;
        int verticesPerLine = areaDetails.verticesPerLine;

        Vector2 topLeftCorner = new Vector2(-1, 1) * areaDetails.resolution / 2f;

        MeshDetails meshDetails = new MeshDetails(verticesPerLine, areaDetails.useFlatshading, lodIncrement);

        int[,] vertexIndexes = new int[verticesPerLine, verticesPerLine];
        int meshVertexIndex    = 0;
        int outsideVertexIndex = -1;

        for (int yIndex = 0; yIndex < verticesPerLine; yIndex++)
        {
            for (int xIndex = 0; xIndex < verticesPerLine; xIndex++)
            {
                bool isOutsideVertex = yIndex == 0 || xIndex == 0 || yIndex == verticesPerLine - 1 || xIndex == verticesPerLine - 1;
                bool isUselessVertex = xIndex > 2 && xIndex < verticesPerLine - 3 && yIndex > 2 && yIndex < verticesPerLine - 3 && ((xIndex - 2) % lodIncrement != 0 || (yIndex - 2) % lodIncrement != 0);

                if (isOutsideVertex)
                {
                    vertexIndexes[xIndex, yIndex] = outsideVertexIndex;
                    outsideVertexIndex--;
                }
                else if (!isUselessVertex)
                {
                    vertexIndexes[xIndex, yIndex] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int yIndex = 0; yIndex < verticesPerLine; yIndex++)
        {
            for (int xIndex = 0; xIndex < verticesPerLine; xIndex++)
            {
                bool isUselessVertex = xIndex > 2 && xIndex < verticesPerLine - 3 && yIndex > 2 && yIndex < verticesPerLine - 3 && ((xIndex - 2) % lodIncrement != 0 || (yIndex - 2) % lodIncrement != 0);

                if (!isUselessVertex)
                {
                    bool isOutsideVertex  = yIndex == 0 || xIndex == 0 || yIndex == verticesPerLine - 1 || xIndex == verticesPerLine - 1;
                    bool isFrontierVertex = (yIndex == 1 || yIndex == verticesPerLine - 2 || xIndex == 1 || xIndex == verticesPerLine - 2) && !isOutsideVertex;
                    bool isMainVertex     = (xIndex - 2) % lodIncrement == 0 && (yIndex - 2) % lodIncrement == 0 && !isOutsideVertex && !isFrontierVertex;
                    bool isInsideVertex   = (yIndex == 2 || yIndex == verticesPerLine - 3 || xIndex == 2 || xIndex == verticesPerLine - 3) && !isOutsideVertex && !isFrontierVertex && !isMainVertex;

                    int vertexIndex = vertexIndexes[xIndex, yIndex];

                    Vector2 uv           = new Vector2(xIndex - 1, yIndex - 1) / (verticesPerLine - 3);
                    Vector2 vertexCoords = topLeftCorner + new Vector2(uv.x, -uv.y) * areaDetails.resolution;
                    float   height       = noiseArea[xIndex, yIndex];

                    if (isInsideVertex)
                    {
                        bool isVertical = xIndex == 2 || xIndex == verticesPerLine - 3;

                        int distanceToMainVertexA = (isVertical ? yIndex - 2 : xIndex - 2) % lodIncrement;
                        int distanceToMainVertexB = lodIncrement - distanceToMainVertexA;

                        float distancePercentage = distanceToMainVertexA / (float)lodIncrement;

                        float heightVertexA = noiseArea[isVertical ? xIndex : xIndex - distanceToMainVertexA, isVertical ? yIndex - distanceToMainVertexA : yIndex];
                        float heightVertexB = noiseArea[isVertical ? xIndex : xIndex + distanceToMainVertexB, isVertical ? yIndex + distanceToMainVertexB : yIndex];

                        height = heightVertexA * (1 - distancePercentage) + heightVertexB * distancePercentage;
                    }

                    meshDetails.AddVertex(new Vector3(vertexCoords.x, height, vertexCoords.y), uv, vertexIndex);

                    bool createTriangle = xIndex < verticesPerLine - 1 && yIndex < verticesPerLine - 1 && (!isInsideVertex || (xIndex != 2 && yIndex != 2));

                    if (createTriangle)
                    {
                        int currentIncrement = (isMainVertex && xIndex != verticesPerLine - 3 && yIndex != verticesPerLine - 3) ? lodIncrement : 1;

                        int vertexAIndex = vertexIndexes[xIndex, yIndex];
                        int vertexBIndex = vertexIndexes[xIndex + currentIncrement, yIndex];
                        int vertexCIndex = vertexIndexes[xIndex, yIndex + currentIncrement];
                        int vertexDIndex = vertexIndexes[xIndex + currentIncrement, yIndex + currentIncrement];

                        meshDetails.AddTriangle(vertexAIndex, vertexDIndex, vertexCIndex);
                        meshDetails.AddTriangle(vertexDIndex, vertexAIndex, vertexBIndex);
                    }
                }
            }
        }

        meshDetails.BuildLighting();

        return(meshDetails);
    }