예제 #1
0
    public static TerrainMeshData GenerateFlatMesh(int chunkSize, int levelOfDetail)
    {
        float topLeftX = (chunkSize - 1) / -2f;
        float topLeftZ = (chunkSize - 1) / 2f;

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int verticesPerLine             = (chunkSize - 1) / meshSimplificationIncrement + 1;

        TerrainMeshData meshData    = new TerrainMeshData(verticesPerLine, verticesPerLine);
        int             vertexIndex = 0;

        for (int y = 0; y < chunkSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < chunkSize; x += meshSimplificationIncrement)
            {
                meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, 0, topLeftZ - y);
                meshData.uvs[vertexIndex]      = new Vector2(x / (float)chunkSize, y / (float)chunkSize);

                if (x < chunkSize - 1 && y < chunkSize - 1)
                {
                    meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);
                    meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
                }

                vertexIndex++;
            }
        }

        return(meshData);
    }
예제 #2
0
    public static TerrainMeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail)
    {
        int   width    = heightMap.GetLength(0);
        int   height   = heightMap.GetLength(1);
        float topLeftX = (width - 1) / -2f;
        float topLeftZ = (height - 1) / 2f;

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int verticesPerLine             = (width - 1) / meshSimplificationIncrement + 1;

        TerrainMeshData meshData    = new TerrainMeshData(verticesPerLine, verticesPerLine);
        int             vertexIndex = 0;

        for (int y = 0; y < height; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < width; x += meshSimplificationIncrement)
            {
                meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, /*heightCurve.Evaluate(heightMap[x, y])*/ heightMap[x, y] * heightMultiplier, topLeftZ - y);
                meshData.uvs[vertexIndex]      = new Vector2(x / (float)width, y / (float)height);

                if (x < width - 1 && y < height - 1)
                {
                    meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);
                    meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
                }

                vertexIndex++;
            }
        }

        return(meshData);
    }
    public static TerrainChunk GenerateTerrainMesh(float[,] heightMap, int levelOfDetail)
    {
        int width  = heightMap.GetLength(0);
        int height = heightMap.GetLength(1);

        float topLeftX = (width - 1) / -2f;
        float topLeftZ = (height - 1) / 2f;

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int verticesPerLine             = (width - 1) / meshSimplificationIncrement + 1;

        TerrainMeshData MeshData = new TerrainMeshData(verticesPerLine, verticesPerLine);

        for (int y = 0; y < height; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < width; x += meshSimplificationIncrement)
            {
                // Add Vertex for this position (index of vertex is width*yPos + xPos)
                int vertexIndex = MeshData.AddVertex(topLeftX + x, heightMap[x, y], topLeftZ - y);

                // Add UV (relative position of vertex on the map)
                MeshData.AddUV(x / (float)width, y / (float)height);

                // Add the 2 triangles facing down right if we're not at the right or bottom border (because there are no more triangles facing bottom right)
                // Triangles are constructed clockwise!
                if (x < width - 1 && y < height - 1)
                {
                    // Create Triangle that goes from current vertex (i) > vertex below right from current vertext (i+width+1) > vertex below current vertex (i+width)
                    MeshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);

                    // Create Triangle that goes from vertex below right current vertex (i+width+1) > current vertex (i) > vertex right from current vertext (i+1)
                    MeshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
                }
            }
        }

        return(MeshData.CreateMesh());
    }
예제 #4
0
    public static TerrainMeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        int skipIncrement   = (levelOfDetail == 0)?1:levelOfDetail * 2;
        int numVertsPerLine = meshSettings.numVertsPerLine;

        Vector2 topLeft = new Vector2(-1, 1) * meshSettings.meshWorldSize / 2f;

        TerrainMeshData meshData = new TerrainMeshData(numVertsPerLine, skipIncrement, meshSettings.useFlatShading);

        int[,] vertexIndicesMap = new int[numVertsPerLine, numVertsPerLine];
        int meshVertexIndex      = 0;
        int outOfMeshVertexIndex = -1;

        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                bool isSkippedVertex   = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);
                if (isOutOfMeshVertex)
                {
                    vertexIndicesMap [x, y] = outOfMeshVertexIndex;
                    outOfMeshVertexIndex--;
                }
                else if (!isSkippedVertex)
                {
                    vertexIndicesMap [x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);

                if (!isSkippedVertex)
                {
                    bool isOutOfMeshVertex      = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                    bool isMeshEdgeVertex       = (y == 1 || y == numVertsPerLine - 2 || x == 1 || x == numVertsPerLine - 2) && !isOutOfMeshVertex;
                    bool isMainVertex           = (x - 2) % skipIncrement == 0 && (y - 2) % skipIncrement == 0 && !isOutOfMeshVertex && !isMeshEdgeVertex;
                    bool isEdgeConnectionVertex = (y == 2 || y == numVertsPerLine - 3 || x == 2 || x == numVertsPerLine - 3) && !isOutOfMeshVertex && !isMeshEdgeVertex && !isMainVertex;

                    int     vertexIndex      = vertexIndicesMap [x, y];
                    Vector2 percent          = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3);
                    Vector2 vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.meshWorldSize;
                    float   height           = heightMap [x, y];

                    if (isEdgeConnectionVertex)
                    {
                        bool  isVertical         = x == 2 || x == numVertsPerLine - 3;
                        int   dstToMainVertexA   = ((isVertical)?y - 2:x - 2) % skipIncrement;
                        int   dstToMainVertexB   = skipIncrement - dstToMainVertexA;
                        float dstPercentFromAToB = dstToMainVertexA / (float)skipIncrement;

                        float heightMainVertexA = heightMap [(isVertical) ? x : x - dstToMainVertexA, (isVertical) ? y - dstToMainVertexA : y];
                        float heightMainVertexB = heightMap [(isVertical) ? x : x + dstToMainVertexB, (isVertical) ? y + dstToMainVertexB : y];

                        height = heightMainVertexA * (1 - dstPercentFromAToB) + heightMainVertexB * dstPercentFromAToB;
                    }

                    meshData.AddVertex(new Vector3(vertexPosition2D.x, height, vertexPosition2D.y), percent, vertexIndex);

                    bool createTriangle = x < numVertsPerLine - 1 && y < numVertsPerLine - 1 && (!isEdgeConnectionVertex || (x != 2 && y != 2));

                    if (createTriangle)
                    {
                        int currentIncrement = (isMainVertex && x != numVertsPerLine - 3 && y != numVertsPerLine - 3) ? skipIncrement : 1;

                        int a = vertexIndicesMap [x, y];
                        int b = vertexIndicesMap [x + currentIncrement, y];
                        int c = vertexIndicesMap [x, y + currentIncrement];
                        int d = vertexIndicesMap [x + currentIncrement, y + currentIncrement];
                        meshData.AddTriangle(a, d, c);
                        meshData.AddTriangle(d, a, b);
                    }
                }
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }