ProcessMesh() public method

public ProcessMesh ( ) : void
return void
Exemplo n.º 1
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail, bool flatshading, MapGenerator mg)
    {
        int   width        = heightMap.GetLength(0);
        int   height       = heightMap.GetLength(1);
        float topLeftX     = (width - 1) / -2f;
        float topLeftZ     = (height - 1) / 2f;
        int   borderedSize = heightMap.GetLength(0);
        int   meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int   verticesPerLine             = (width - 1) / meshSimplificationIncrement + 1;
        int   borderVertexIndex           = -1;

        MeshData meshData    = new MeshData(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]) * 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++;
            }
        }
        mg.ColorMap();
        meshData.ProcessMesh(flatshading);
        return(meshData);
    }
Exemplo n.º 2
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;

        int meshSize             = heightMap.GetLength(0) - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = heightMap.GetLength(0) - 2;

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


        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[meshSize, meshSize];
        int meshVertexIndex = 0;

        for (int y = 0; y < meshSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < meshSize; x += meshSimplificationIncrement)
            {
                vertexIndicesMap[x, y] = meshVertexIndex;
                meshVertexIndex++;
            }
        }

        for (int y = 0; y < meshSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < meshSize; x += meshSimplificationIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];

                float   height         = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);
                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < meshSize - 1 && y < meshSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];
                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 3
0
        public Task <MeshData> GenerateTerrainMeshNew(float[,] heightMap, int levelOfDetail)
        {
            int skipIncrement    = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
            var vertexIndicesMap = InitializeVertexIndicesMap(skipIncrement);

            var meshData = new MeshData(numVertsPerLine, skipIncrement, settings.useFlatShading);

            var meshVertexIndex      = 0;
            var outOfMeshVertexIndex = -1;



            for (var y = 0; y < numVertsPerLine; ++y)
            {
                for (var x = 0; x < numVertsPerLine; ++x)
                {
                    var v = new VertexInfo(x, y, skipIncrement, heightMap, vertexIndicesMap);
                    if (v.isSkipped)
                    {
                        continue;
                    }

                    var vertexIndex      = v.VertexIndex;
                    var percent          = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3);
                    var vertexPosition2D = settings.TopLeft + new Vector2(percent.x, -percent.y) * settings.meshWorldSize;

                    if (v.isEdgeConnection)
                    {
                        var edgeConnectionVertexData = new EdgeConnectionVertexData(vertexIndex, v.VertexIndexCoordA, v.VertexIndexCoordB, v.dstPercentFromAToB);
                        meshData.DeclareEdgeConnectionVertex(edgeConnectionVertexData);
                    }

                    try {
                        meshData.AddVertex(new Vector3(vertexPosition2D.x, v.height, vertexPosition2D.y), percent, vertexIndex);
                    }
                    catch (IndexOutOfRangeException)
                    {
                        //Debug.Log(vertexIndex);
                    }

                    if (!v.shouldCreateTriangle)
                    {
                        continue;
                    }

                    int[] corners = v.Corners;

                    meshData.AddTriangle(corners[0], corners[3], corners[2]);
                    meshData.AddTriangle(corners[3], corners[0], corners[1]);
                }
            }

            meshData.ProcessMesh();

            return(Task.FromResult(meshData));
        }
Exemplo n.º 4
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading, bool buildingWall)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        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;

        MeshData meshData    = new MeshData(verticesPerLine, verticesPerLine, useFlatShading);
        int      vertexIndex = 0;

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

                meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height);

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

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 5
0
    // Creates a mesh from a 2D height map
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve,
                                               int levelOfDetail, bool useFlatShading)
    {
        // Each thread will have its own height curve object
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);         // Create a new animation curve at the start to avoid errors

        int   width    = heightMap.GetLength(0);
        int   height   = heightMap.GetLength(1);
        float topLeftX = (width - 1) / -2f;         // Scales the lefmost point so that the mesh is centered on the screen
        float topLeftZ = (height - 1) / 2f;

        // The number of vertices to skip over (1 draws all vertices)
        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1: levelOfDetail * 2;
        int verticesPerLine             = (width - 1) / meshSimplificationIncrement + 1;

        MeshData meshData    = new MeshData(verticesPerLine, verticesPerLine, useFlatShading);
        int      vertexIndex = 0;                                     // Current index of the vertices array

        for (int y = 0; y < height; y += meshSimplificationIncrement) // Loop through the height map
        {
            for (int x = 0; x < width; x += meshSimplificationIncrement)
            {
                meshData.vertices [vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap [x, y]) * heightMultiplier, topLeftZ - y);
                // Each vertex's position in the map is represented as a percentage
                meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height);

                // Ignore indexes at the right and bottom of the mesh
                if (x < width - 1 && y < height - 1)
                {
                    meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);        // First triangle
                    meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);                      // Second triangle
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 6
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        int mapWidth  = heightMap.GetLength(0);
        int mapHeight = heightMap.GetLength(1);

        float topLeftX = (mapWidth - 1) / -2f;
        float topLeftZ = (mapHeight - 1) / 2f;

        MeshData meshData    = new MeshData(mapWidth, mapHeight);
        int      vertexIndex = 0;

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                float height = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;

                Vector2 uv       = new Vector2(x / (float)mapWidth, y / (float)mapHeight);
                Vector3 position = new Vector3(topLeftX + x, height, topLeftZ - y);

                meshData.AddVertex(position, uv, vertexIndex);

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

                vertexIndex = vertexIndex + 1;
            }
        }

        meshData.ProcessMesh();
        return(meshData);
    }
Exemplo n.º 7
0
    public MeshData GenerateMeshData(MeshSettings meshSettings, int lod)
    {
        float topLeftX = (width - 1) / -2f;
        float topLeftZ = (height - 1) / 2f;

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

        MeshData meshData    = new MeshData(verticesPerLine, verticesPerLine, meshSettings.useFlatShading);
        int      vertexIndex = 0;

        for (int y = 0; y < height; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < width; x += meshSimplificationIncrement)
            {
                float heightY = values[x, y];

                Vector3 vertice = new Vector3((topLeftX + x) * meshSettings.meshScale, heightY,
                                              (topLeftZ - y) * meshSettings.meshScale);
                Vector2 uv = new Vector2(x / (float)width, y / (float)height);

                meshData.AddVertice(vertexIndex, vertice, uv);

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

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 8
0
    public static MeshData GenerateTerrianMesh(float[,] heightMap, float heightMulti, int lod, AnimationCurve curve)
    {
        int borderSize = heightMap.GetLength(0);

        int meshSimpleInc = (lod == 0) ? 1 : lod * 2;

        int meshSize = (borderSize - 1) / meshSimpleInc + 1;

        var meshData = new MeshData(meshSize);


        float topLeftX = borderSize / -2;
        float topLeftZ = borderSize / 2;

        float[,] newHeightMap = new float[borderSize, borderSize];
        Buffer.BlockCopy(heightMap, 0, newHeightMap, 0, borderSize * borderSize);

        int[,] vertexIdxMap = new int[meshSize, meshSize];

        int meshIdx = 0;

        for (int y = 0; y < borderSize; y += meshSimpleInc)
        {
            for (int x = 0; x < borderSize; x += meshSimpleInc)
            {
                vertexIdxMap[y / meshSimpleInc, x / meshSimpleInc] = meshIdx++;
            }
        }

        for (int y = 0; y < borderSize; y += meshSimpleInc)
        {
            for (int x = 0; x < borderSize; x += meshSimpleInc)
            {
                float height = curve.Evaluate(heightMap[y, x]) * heightMulti;

                newHeightMap[y, x] = height;

                Vector3 vertexPos = new Vector3(x, height, y);
                Vector2 uv        = new Vector2(x / (float)borderSize, y / (float)borderSize);
                meshData.AddVertex(vertexPos, uv, vertexIdxMap[y / meshSimpleInc, x / meshSimpleInc]);

                if (x < borderSize - meshSimpleInc && y < borderSize - meshSimpleInc)
                {
                    int xx = x / meshSimpleInc;
                    int yy = y / meshSimpleInc;
                    int a  = vertexIdxMap[yy, xx];
                    int b  = vertexIdxMap[yy, xx + 1];
                    int c  = vertexIdxMap[yy + 1, xx];
                    int d  = vertexIdxMap[yy + 1, xx + 1];

                    meshData.AddTriangle(c, b, a);
                    meshData.AddTriangle(c, d, b);
                }
            }
        }

        meshData.meshSimpleInc = meshSimpleInc;
        meshData.heightMap     = newHeightMap;

        meshData.ProcessMesh();

        return(meshData);
    }
    //The return type for this is MeshData so that threading can be implemented later on, thereby heavily increasing performance
    //An animation curve is used to define the height of various specific location groups, such as making "water" appear flat
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatshading)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);
        int            meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int            borderedSize         = heightMap.GetLength(0);
        int            meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int            meshSizeUnsimplified = borderedSize - 2;

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        //The mesh, using this along with the vertex array, will begin in the center of the plane
        float topLeftX = (meshSizeUnsimplified - 1) / -2f;
        float topLeftZ = (meshSizeUnsimplified - 1) / 2f;

        MeshData meshData = new MeshData(verticesPerLine, useFlatshading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        //In order to account for border vertices in the terrain for lighting/normals purposes, run a loop to identify where they are
        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        //The heightMap quite literally corresponds with how high the plane is at coordinates (x,y)
        //The uvs are calculated using mesh size, not bordered size
        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int     vertexIndex    = vertexIndicesMap[x, y];
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                //Create 2 triangles according to the vertex indices map
                //Imagine a square with each point indicated like so:
                //
                //A---B
                //| + |
                //C---D
                //
                //The triangles needing to be calculated and added into the mesh data are triangles ADC and DAB
                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];
                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }
                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 10
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);             // each thread has its on own heightCurve object, no need for locking

        int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2;

        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;            //independent of lod

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

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap [x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap [x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int     vertexIndex = vertexIndicesMap [x, y];
                Vector2 percent     = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);

                float   height         = heightCurve.Evaluate(heightMap [x, y]) * heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap [x, y];
                    int b = vertexIndicesMap [x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap [x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap [x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);                      //triangle adc
                    meshData.AddTriangle(d, a, b);                      //triangle dab
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();                 // run on seperate thread - since generate terrain mesh is run on different thread

        return(meshData);
    }
    // CREDIT: Sebastian Lague: https://www.youtube.com/channel/UCmtyQOKKmrMVaKuRXz02jbQ

    public static MeshData GenerateTerrainMesh(float[,] heightMap, int levelOfDetail, bool useFlatShading)
    {
        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; // 2

        int borderedSize         = heightMap.GetLength(0);                              // 7
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;      // 3
        int meshSizeUnsimplified = borderedSize - 2;                                    // 5

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


        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;
        // if full (1): 5     4 + 1
        // if low (2): 3      2 + 1
        // if lower (4): 2    1 + 1
        int tilesPerSide = borderedSize - 3;

        for (int i = 0; i < levelOfDetail; i++)
        {
            tilesPerSide /= 2;
            if (tilesPerSide < 1)
            {
                tilesPerSide = 1;
                break;
            }
        }
        verticesPerLine = tilesPerSide + 1;
        //Debug.Log("Generating mesh with " + verticesPerLine + " verticies per line");

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        int curIncrement = 1;

        //for (int y = 0; y < borderedSize; y++) {
        //	for (int x = 0; x < borderedSize; x++) {
        //		vertexIndicesMap[x, y] = 100;
        //	}
        //}
        for (int y = 0; y < borderedSize; y += curIncrement)
        {
            for (int x = 0; x < borderedSize; x += curIncrement)
            {
                if (x == 0 || x == borderedSize - 2)
                {
                    curIncrement = 1;
                }
                else
                {
                    curIncrement = meshSimplificationIncrement;
                }

                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;
                //Debug.Log(new Vector2Int(x, y) + " border: " + isBorderVertex);
                if (isBorderVertex)
                {
                    vertexIndicesMap [x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap [x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
            if (y == 0 || y == borderedSize - 2)
            {
                curIncrement = 1;
            }
            else
            {
                curIncrement = meshSimplificationIncrement;
            }
        }
        //for (int y = 0; y < borderedSize; y++) {
        //	string lineStr = y + " | ";
        //	for (int x = 0; x < borderedSize; x++) {
        //		int val = vertexIndicesMap[x, y];
        //		lineStr += val == 100 ? "N " : val + " ";
        //	}
        //	Debug.Log(lineStr);
        //}

        int curIncrementX;
        int curIncrementY;

        for (int y = 0; y < borderedSize; y += curIncrementY)
        {
            if (y == 0 || y == borderedSize - 2)
            {
                curIncrementY = 1;
            }
            else
            {
                curIncrementY = meshSimplificationIncrement;
            }
            for (int x = 0; x < borderedSize; x += curIncrementX)
            {
                if (x == 0 || x == borderedSize - 2)
                {
                    curIncrementX = 1;
                }
                else
                {
                    curIncrementX = meshSimplificationIncrement;
                }

                int vertexIndex = vertexIndicesMap [x, y];
                //Vector2 percent = new Vector2 ((x- curIncrement) / (float)meshSize, (y- curIncrement) / (float)meshSize);
                float height = heightMap [x, y];
                //Vector3 vertexPosition = new Vector3 (topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);
                Vector3 vertexPosition = new Vector3(topLeftX + x - 1, height, topLeftZ - y + 1);

                meshData.AddVertex(vertexPosition, Vector2.zero, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap [x, y];
                    int b = vertexIndicesMap [x + curIncrementX, y];
                    int c = vertexIndicesMap [x, y + curIncrementY];
                    int d = vertexIndicesMap [x + curIncrementX, y + curIncrementY];
                    //Debug.Log(new Vector2Int(x, y) + " | Inc: " + new Vector2Int(curIncrementX, curIncrementY) + " | a: " + a + " b: " + b + " c: " + c + " d: " + d);
                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 12
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;

        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

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


        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, meshSettings.useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int     vertexIndex    = vertexIndicesMap[x, y];
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = heightMap[x, y];
                Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified) * meshSettings.meshScale, height, (topLeftZ - percent.y * meshSizeUnsimplified) * meshSettings.meshScale);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];
                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        int skipIncrement = levelOfDetail == 0 ? 1 : levelOfDetail * 2;

        int numVertsPerLine = meshSettings.NumVerticesPerLine;

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

        MeshData meshData = new MeshData(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 isMainVertex      = ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);
                bool isSkippedVertex   = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && isMainVertex;

                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);

                    float   height           = heightMap[x, y];
                    Vector2 vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.MeshWorldSize;

                    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 pointA = vertexIndicesMap[x, y];
                        int pointB = vertexIndicesMap[x + currentIncrement, y];
                        int pointC = vertexIndicesMap[x, y + currentIncrement];
                        int pointD = vertexIndicesMap[x + currentIncrement, y + currentIncrement];

                        /* Setting the triangle according to the square point:
                         *
                         *     a    b
                         *      O    O
                         *
                         *      O    O
                         *     c    d
                         *
                         * Run clockwise to define the 2 triangles we have
                         * Triangle A = adc
                         * Triangle B = dab
                         */
                        meshData.AddTriangle(pointA, pointD, pointC);
                        meshData.AddTriangle(pointD, pointA, pointB);
                    }
                }
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 14
0
        public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
        {
            var skipIncrement   = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
            var numVertsPerLine = meshSettings.numVertsPerLine;

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

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

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

            for (var y = 0; y < numVertsPerLine; ++y)
            {
                for (var x = 0; x < numVertsPerLine; ++x)
                {
                    var isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                    var 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 (var y = 0; y < numVertsPerLine; ++y)
            {
                for (var x = 0; x < numVertsPerLine; ++x)
                {
                    var isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);

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

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

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

                            var coordA = new Coord((isVertical) ? x : x - dstToMainVertexA, (isVertical) ? y - dstToMainVertexA : y);
                            var coordB = new Coord((isVertical) ? x : x + dstToMainVertexB, (isVertical) ? y + dstToMainVertexB : y);

                            var heightMainVertexA = heightMap[coordA.x, coordA.y];
                            var heightMainVertexB = heightMap[coordB.x, coordB.y];

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

                            var edgeConnectionVertexData = new EdgeConnectionVertexData(vertexIndex, vertexIndicesMap[coordA.x, coordA.y], vertexIndicesMap[coordB.x, coordB.y], dstPercentFromAToB);
                            meshData.DeclareEdgeConnectionVertex(edgeConnectionVertexData);
                        }

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

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

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

                            var a = vertexIndicesMap[x, y];
                            var b = vertexIndicesMap[x + currentIncrement, y];
                            var c = vertexIndicesMap[x, y + currentIncrement];
                            var d = vertexIndicesMap[x + currentIncrement, y + currentIncrement];
                            meshData.AddTriangle(a, d, c);
                            meshData.AddTriangle(d, a, b);
                        }
                    }
                }
            }
            meshData.ProcessMesh();
            return(meshData);
        }
Exemplo n.º 15
0
    //generates meshData from appropriate data passed in
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        //how many vertices to skip, scales with LOD (this being 2 means we skip every other vertex)
        int skipIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;

        //number of verts to a side in the mesh
        int numVertsPerLine = meshSettings.numVertsPerLine;

        //Top left X and Z of the verticies in the soon-to-be-created meshData
        Vector2 topLeft = new Vector2(-1, -1) * meshSettings.meshWorldSize / 2f;

        //creates a new meshdata with the correct amount of verticies for the level of detail specified
        MeshData meshData = new MeshData(numVertsPerLine, skipIncrement, meshSettings.useFlatShading);

        /*the map of verticies for dealing with the lighting errors that occur at the edge of each mesh looks like this on a 3x3 mesh
         * -1 -2  -3  -4  -5
         * -6  0   1   2  -7
         * -8  3   4   5  -9
         *-10  6   7   8  -11
         *-12 -13 -14 -15 -16
         * because negative indices vertexes aren't included in the final mesh. This is obviously hard to create so that's what these variables and for loops are for
         */
        int[,] vertexIndiciesMap = new int[numVertsPerLine, numVertsPerLine];
        int meshVertexIndex      = 0;
        int outOfMeshVertexIndex = -1;

        //creating the map of vertices
        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                //check if we're on the outside border fo the mesh
                bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                //check if we're skipping the verice for LOD stuff
                bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);

                if (isOutOfMeshVertex)
                {
                    vertexIndiciesMap[x, y] = outOfMeshVertexIndex;
                    outOfMeshVertexIndex--;
                }
                else if (!isSkippedVertex)
                {
                    vertexIndiciesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        //runs through each vertice according to LOD
        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                //check if we're skipping the verice for LOD stuff
                bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);

                if (!isSkippedVertex)
                {
                    //check what kind of vertex we are
                    //https://www.desmos.com/calculator/bcagu8b0vn
                    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;

                    //gets the correct vertexIndex from the indicies map we just made
                    int vertexIndex = vertexIndiciesMap[x, y];
                    //used to map the texture to the mesh
                    Vector2 percent = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3);
                    //we flip y in order to alighn the unity editor z axis with the programming y axis
                    Vector2 vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.meshWorldSize;
                    //the height of the vertex at the given x, y coordinates
                    float height = heightMap[x, y];

                    //this is to make the edgeconnection vertices match up with the mesh when it's at a different LOD by linearly interpolating between the 2 closest vertices' heights
                    if (isEdgeConnectionVertex)
                    {
                        bool isVertical       = x == 2 || x == numVertsPerLine - 3;
                        int  dstToMainVertexA = ((isVertical) ? y - 2 : x - 2) % skipIncrement; // distance to the closest main vertex above
                        int  dstToMainVertexB = skipIncrement - dstToMainVertexA;               // distance to the closest main vertex below

                        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);

                    //should we create a triangle
                    bool createTriangle = x < numVertsPerLine - 1 && y < numVertsPerLine - 1 && (!isEdgeConnectionVertex || (x != 2 && y != 2));

                    //if we aren't on the finishing edges/half of the outside edge
                    if (createTriangle)
                    {
                        //the size of the triangle
                        int currentIncrement = (isMainVertex && x != numVertsPerLine - 3 && y != numVertsPerLine - 3) ? skipIncrement : 1;

                        //the indicies our 2 triangles are being made of
                        int a = vertexIndiciesMap[x, y];
                        int b = vertexIndiciesMap[x + currentIncrement, y];
                        int c = vertexIndiciesMap[x, y + currentIncrement];
                        int d = vertexIndiciesMap[x + currentIncrement, y + currentIncrement];
                        //adding triangles to the mesh Data
                        meshData.AddTriangle(a, d, c);
                        meshData.AddTriangle(d, a, b);
                    }
                }
            }
        }

        //calculate the normals
        meshData.ProcessMesh();

        //return the meshData
        return(meshData);
    }
Exemplo n.º 16
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        var skipIncrement   = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int numVertsPerLine = meshSettings.NumberOfVerticesPerLine;

        Vector2 topLeft = new Vector2(-1, 1) * meshSettings.MeshWorldSize / 0.5f;

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

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

        for (var y = 0; y < numVertsPerLine; y++)
        {
            for (var 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 (var y = 0; y < numVertsPerLine; y++)
        {
            for (var 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;

                    var vertexIndex = vertexIndicesMap[x, y];
                    var percent     = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3);

                    var vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.MeshWorldSize;
                    var height           = heightMap[x, y];

                    if (isEdgeConnectionVertex)
                    {
                        bool  isVertical              = x == 2 || x == numVertsPerLine - 3;
                        int   distanceToMainVertexA   = ((isVertical ? y : x) - 2) % skipIncrement;
                        int   distanceToMainVertexB   = skipIncrement - distanceToMainVertexA;
                        float distancePercentFromAToB = distanceToMainVertexA / (float)skipIncrement;

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

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

                    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;


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

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 17
0
    public static MeshData GenerateMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail, bool useFlatShading)
    {
        AnimationCurve meshHeightCurve = new AnimationCurve(heightCurve.keys);

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;//if level of detail is set to 0 make it equal to 1 instead of multiplying it by two


        int   borderedSize         = heightMap.GetLength(0);//border around verteces used to calculate normals
        int   meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int   meshSizeUnsimplified = borderedSize - 2;
        float topLeftX             = (meshSizeUnsimplified - 1) / -2f;
        float topLeftZ             = (meshSizeUnsimplified - 1) / 2f;

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;


        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;
                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int     vertexIndex    = vertexIndicesMap[x, y];
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = meshHeightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);//toplefts allow the map to be centered

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)//these two lines create two triangles out of the vertices
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex += 1;
            }
        }
        meshData.ProcessMesh();
        return(meshData);//returns meshData for threading so that the game doesnt freeze up when we generate chunks
    }
Exemplo n.º 18
0
    /**
     * Method that generates the mesh values, including the vertices and triangles
     * @param heightMap The height map which supplies height values to the mesh
     * @param heightMultiplier Value that is multiplied with the height; allows the elevation of the terrain to be more visible
     * @param _heightCurve The curve that determines the level of effect the heightMultiplier has on a given elevation
     * @param levelOfDetail A value that determines the number of vertices and triangles in the mesh
     * @param useFlatShading Bool that determines if flat shading is enables or not
     * @return meshData The data of the mesh
     */
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading)
    {
        // Created a new animation curve to avoid a weird issue from occurring
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        // Implement level of detail; avoid the zero case
        int meshIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;

        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - (2 * meshIncrement);
        int meshSizeUnsimplified = borderedSize - 2;

        // Values used in calculating the mesh vertices
        float topLeftX = (meshSizeUnsimplified - 1) / -2f;
        float topLeftZ = (meshSizeUnsimplified - 1) / 2f;

        int verticesPerLine = ((meshSize - 1) / meshIncrement) + 1;

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex     = 0;
        int borderedVertexIndex = -1;

        // Implement border indices and mesh indices
        for (int y = 0; y < borderedSize; y += meshIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshIncrement)
            {
                bool isBorderVertex = (y == 0) || (y == borderedSize - 1) || (x == 0) || (x == borderedSize - 1);

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderedVertexIndex;
                    borderedVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        // Where the mesh values are all assigned
        for (int y = 0; y < borderedSize; y += meshIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];

                Vector2 percent        = new Vector2((x - meshIncrement) / (float)meshSize, (y - meshIncrement) / (float)meshSize);
                float   height         = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + (percent.x * meshSizeUnsimplified), height, topLeftZ - (percent.y * meshSizeUnsimplified));

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < (borderedSize - 1) && y < (borderedSize - 1))
                {
                    // Vertices for our two triangles
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshIncrement, y];
                    int c = vertexIndicesMap[x, y + meshIncrement];
                    int d = vertexIndicesMap[x + meshIncrement, y + meshIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
    /// <summary>
    /// Generates mesh data from a height map with customisable settings.
    /// </summary>
    /// <param name="heightMap">The height map values.</param>
    /// <param name="meshSettings">Mesh settings to vary the mesh.</param>
    /// <param name="levelOfDetail">The level of detail of the mesh.</param>
    /// <returns>Collections of vertices and triangles that make up the mesh.</returns>
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        // the amount of vertices skipped each line
        int skipIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        // the number of vertices in each line
        int numVertsPerLine = meshSettings.NumVertsPerLine;

        // the top left coordinate of the mesh
        Vector2 topLeft = new Vector2(-1, 1) * meshSettings.MeshWorldSize / 2.0f;
        // initialises a mesh's vertices and triangles
        MeshData meshData = new MeshData(numVertsPerLine, skipIncrement, meshSettings.useFlatShading);

        // the index of each vertex
        int[,] vertexIndicesMap = new int[numVertsPerLine, numVertsPerLine];
        // the index of the current vertex
        int meshVertexIndex = 0;
        // the index of the current vertex not in the mesh bounds
        int outOfMeshVertexIndex = -1;

        // for every index of the index map, determine if the vertex is in or out of the mesh
        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                // determines if the vertex is out of the mesh
                bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                // determines if the vertex is skipped
                bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 &&
                                       y > 2 && y < numVertsPerLine - 3 &&
                                       ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);
                // adds an out of mesh vertex index to the map
                if (isOutOfMeshVertex)
                {
                    vertexIndicesMap[x, y] = outOfMeshVertexIndex;
                    outOfMeshVertexIndex--;
                }
                // adds an in mesh vertex index to the map if it is not skipped
                else if (!isSkippedVertex)
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        // adds the vertex positions to the mesh data
        for (int y = 0; y < numVertsPerLine; y++)
        {
            for (int x = 0; x < numVertsPerLine; x++)
            {
                // determines if the vertex is skipped
                bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 &&
                                       y > 2 && y < numVertsPerLine - 3 &&
                                       ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0);
                // checks if the vertex is not skipped
                if (!isSkippedVertex)
                {
                    // determines if the vertex is out of the mesh
                    bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                    // determines if the vertex is on the edge
                    bool isMeshEdgeVertex = (y == 1 || y == numVertsPerLine - 2 || x == 1 || x == numVertsPerLine - 2) && !isOutOfMeshVertex;
                    // determines if the vertex is counted
                    bool isMainVertex = (x - 2) % skipIncrement == 0 && (y - 2) % skipIncrement == 0 && !isOutOfMeshVertex && !isMeshEdgeVertex;
                    // determines if the vertex is being connected to
                    bool isEdgeConnectionVertex = (y == 2 || y == numVertsPerLine - 3 || x == 2 || x == numVertsPerLine - 3) && !isOutOfMeshVertex && !isMeshEdgeVertex && !isMainVertex;

                    // the index of the vertex in the mesh
                    int vertexIndex = vertexIndicesMap[x, y];
                    // calculates the vertex's position as a percentage between main vertices
                    Vector2 percent = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3);
                    // gets the 2D position of the vertex
                    Vector2 vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.MeshWorldSize;
                    // gets the height value of the vertex from the height map
                    float height = heightMap[x, y];

                    // checks if the vertex is being connected to along the edge
                    if (isEdgeConnectionVertex)
                    {
                        // determines if the connection is along the left or right side
                        bool isVertical = x == 2 || x == numVertsPerLine - 3;
                        // gets the distances to the main vertices
                        int distToMainVertexA = ((isVertical) ? y - 2 : x - 2) % skipIncrement;
                        int distToMainVertexB = skipIncrement - distToMainVertexA;
                        // gets the distance as a percentage between the two
                        float distPercentFromAToB = distToMainVertexA / (float)skipIncrement;

                        // gets the height of the two vertices
                        float heightOfMainVertexA = heightMap[(isVertical) ? x : x - distToMainVertexA, (isVertical) ? y - distToMainVertexA : y];
                        float heightOfMainVertexB = heightMap[(isVertical) ? x : x + distToMainVertexB, (isVertical) ? y + distToMainVertexB : y];

                        // averages out the height
                        height = heightOfMainVertexA * (1 - distPercentFromAToB) + heightOfMainVertexB * distPercentFromAToB;
                    }

                    // adds the vertex to the mesh
                    meshData.AddVertex(new Vector3(vertexPosition2D.x, height, vertexPosition2D.y), percent, vertexIndex);

                    // determines if a triangle should be made based on if it is not on an edge
                    bool createTriangle = x < numVertsPerLine - 1 && y < numVertsPerLine - 1 && (!isEdgeConnectionVertex || (x != 2 && y != 2));
                    // checks if a triangle should be made
                    if (createTriangle)
                    {
                        int currentIncrement = (isMainVertex && x != numVertsPerLine - 3 && y != numVertsPerLine - 3) ? skipIncrement : 1;

                        // gets the 4 vertices of a tile of the mesh
                        int a = vertexIndicesMap[x, y];
                        int b = vertexIndicesMap[x + currentIncrement, y];
                        int c = vertexIndicesMap[x, y + currentIncrement];
                        int d = vertexIndicesMap[x + currentIncrement, y + currentIncrement];
                        // adds 2 triangles to make up a tile
                        meshData.AddTriangle(a, d, c);
                        meshData.AddTriangle(d, a, b);
                    }
                }
            }
        }

        // calculates the normals of the mesh
        meshData.ProcessMesh();

        return(meshData);
    }
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        // so further meshes don't have to be as detailed
        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;

        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

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

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, meshSettings.useFlatShading);

        // int vertexIndex = 0;

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];

                // make sure the UVs are properly centered by subtracting meshSimplificationIncrement
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = heightMap[x, y];
                Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified), height, (topLeftZ - percent.y * meshSizeUnsimplified));
                //Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified) * meshSettings.meshScale, height, (topLeftZ - percent.y * meshSizeUnsimplified) * meshSettings.meshScale);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                // if not bottom or far right, add square
                //    x,y --- x+1,y
                //      |  \  |
                //  x,y+i --- x+i,y+i
                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);    // return meshData, not mesh for treading later
    }
Exemplo n.º 21
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        int     skipIncrement   = levelOfDetail * 2;
        int     verticesPerLine = meshSettings.numVerticesPerLine;
        Vector2 topLeft         = new Vector2(-1, 1) * meshSettings.meshWorldSize / 2f;

        if (levelOfDetail == 0)
        {
            skipIncrement = 1;
        }

        MeshData meshData = new MeshData(verticesPerLine, skipIncrement, meshSettings.useFlatShading);

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

        for (int z = 0; z < verticesPerLine; z++)
        {
            for (int x = 0; x < verticesPerLine; x++)
            {
                bool isOutOfMeshVertex = z == 0 || z == verticesPerLine - 1 || x == 0 || x == verticesPerLine - 1;
                bool isSkippedVertex   = MeshGenerator.isSkippedVertex(skipIncrement, verticesPerLine, z, x);

                if (isOutOfMeshVertex)
                {
                    vertexIndicesMap[x, z] = outOfMeshVertexIndex;
                    outOfMeshVertexIndex--;
                }
                else if (!isSkippedVertex)
                {
                    vertexIndicesMap[x, z] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int z = 0; z < verticesPerLine; z++)
        {
            for (int x = 0; x < verticesPerLine; x++)
            {
                bool isSkippedVertex = MeshGenerator.isSkippedVertex(skipIncrement, verticesPerLine, z, x);

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

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

                    if (isEdgeConnectionVertex)
                    {
                        bool isVertical            = x == 2 || x == verticesPerLine - 3;
                        int  distanceToMainVertexA = isVertical ? z : x;
                        distanceToMainVertexA = (distanceToMainVertexA - 2) % skipIncrement;
                        int   distanceToMainVertexB   = skipIncrement - distanceToMainVertexA;
                        float distancePercentFromAToB = distanceToMainVertexA / (float)skipIncrement;

                        float heightMainVertexA = heightMap[(isVertical) ? x : x - distanceToMainVertexA,
                                                            (isVertical) ? z - distanceToMainVertexA : z];
                        float heightMainVertexB = heightMap[(isVertical) ? x : x + distanceToMainVertexB,
                                                            (isVertical) ? z + distanceToMainVertexB : z];

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

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

                    bool shouldCreateTriangle = x < verticesPerLine - 1 && z < verticesPerLine - 1 &&
                                                (!isEdgeConnectionVertex || (x != 2 && z != 2));

                    if (shouldCreateTriangle)
                    {
                        int currentIncrement = 1;
                        if (isMainVertex && x != verticesPerLine - 3 && z != verticesPerLine - 3)
                        {
                            currentIncrement = skipIncrement;
                        }


                        int a = vertexIndicesMap[x, z];
                        int b = vertexIndicesMap[x + currentIncrement, z];
                        int c = vertexIndicesMap[x, z + currentIncrement];
                        int d = vertexIndicesMap[x + currentIncrement, z + currentIncrement];

                        meshData.AddTriangle(a, d, c);
                        meshData.AddTriangle(d, a, b);
                    }
                }
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 22
0
    public static MeshData TestMeshData(float[,] heightMap, MeshSettings meshSettings)
    {
        Vector2 topLeft = new Vector2(-1, 1) * meshSettings.meshWorldSize / 2;

        int numVertsPerLine = meshSettings.numVertsPerLine;

        MeshData meshData = new MeshData(numVertsPerLine);

        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;

                if (isOutOfMeshVertex)
                {
                    vertexIndicesMap[x, y] = outOfMeshVertexIndex;
                    outOfMeshVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }


        for (int x = 0; x < numVertsPerLine; x++)
        {
            for (int y = 0; y < numVertsPerLine; y++)
            {
                //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 = !isOutOfMeshVertex && !isMeshEdgeVertex;

                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];

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

                bool createTriangle = x < numVertsPerLine - 1 && y < numVertsPerLine - 1;

                if (createTriangle)
                {
                    int currentIncrement = 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);
    }
	public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading) {
		AnimationCurve heightCurve = new AnimationCurve (_heightCurve.keys);

		int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2;

		int borderedSize = heightMap.GetLength (0);
		int meshSize = borderedSize - 2*meshSimplificationIncrement;
		int meshSizeUnsimplified = borderedSize - 2;

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


		int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

		MeshData meshData = new MeshData (verticesPerLine,useFlatShading);

		int[,] vertexIndicesMap = new int[borderedSize,borderedSize];
		int meshVertexIndex = 0;
		int borderVertexIndex = -1;

		for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) {
			for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) {
				bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

				if (isBorderVertex) {
					vertexIndicesMap [x, y] = borderVertexIndex;
					borderVertexIndex--;
				} else {
					vertexIndicesMap [x, y] = meshVertexIndex;
					meshVertexIndex++;
				}
			}
		}

		for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) {
			for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) {
				int vertexIndex = vertexIndicesMap [x, y];
				Vector2 percent = new Vector2 ((x-meshSimplificationIncrement) / (float)meshSize, (y-meshSimplificationIncrement) / (float)meshSize);
				float height = heightCurve.Evaluate (heightMap [x, y]) * heightMultiplier;
				Vector3 vertexPosition = new Vector3 (topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

				meshData.AddVertex (vertexPosition, percent, vertexIndex);

				if (x < borderedSize - 1 && y < borderedSize - 1) {
					int a = vertexIndicesMap [x, y];
					int b = vertexIndicesMap [x + meshSimplificationIncrement, y];
					int c = vertexIndicesMap [x, y + meshSimplificationIncrement];
					int d = vertexIndicesMap [x + meshSimplificationIncrement, y + meshSimplificationIncrement];
					meshData.AddTriangle (a,d,c);
					meshData.AddTriangle (d,a,b);
				}

				vertexIndex++;
			}
		}

		meshData.ProcessMesh ();

		return meshData;

	}
    // this returns MeshData (instead of Mesh) because we need the individual data points that allow multi-threading to be possible
    public static MeshData GenerateTerrainMeshData(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool applyFlatShading)
    {
        // each thread has its own heightCurve with this statement (so no wild discrepancies as a result)
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        int borderedSize = heightMap.GetLength(0);

        int meshSimplificationIncrement = levelOfDetail == 0 ? 1 : levelOfDetail * 2;

        int meshSizeSimplified   = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

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

        int verticesPerLine = (meshSizeSimplified - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, applyFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];

        int borderVertexIndex = -1;
        int meshVertexIndex   = 0;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];

                Vector2 percent = new Vector2((x - meshSimplificationIncrement) / (float)meshSizeSimplified, (y - meshSimplificationIncrement) / (float)meshSizeSimplified);

                float   height         = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 25
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float meshHeightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

        float topLeftX = (meshSizeUnsimplified - 1) / -2f; // Vai servir para centrar verticalmente
        float topLeftZ = (meshSizeUnsimplified - 1) / 2f;  // Vai servir para centrar horizontalmente

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];
                // O UV é posição em relação ao mapa, em percentagem (0 a 1)
                Vector2 percent = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);

                float height = heightCurve.Evaluate(heightMap[x, y]) * meshHeightMultiplier;

                // A posição dos vértices na Mesh é baseado no canto superior esquerdo, para centrar
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                // Calcular os triângulos ligados a cada vértice, que está no mapa de vértices
                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    // Estamos no vértice a, vamos adicionar os dois triângulos abaixo.
                    // A ORDEM DE ROTACAO É IMPORTANTE!!!
                    // a - b
                    // | \ |
                    // c - d
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    // Triângulo definido pelos vértices: a-d-c
                    meshData.AddTriangles(a, d, c);
                    // Triângulo definido pelos véritices: d-a-b
                    meshData.AddTriangles(d, a, b);
                }
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }
Exemplo n.º 26
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier,
                                               AnimationCurve heightCurve, int levelOfDetail, bool useFlatShading)
    {
        //cf meshSize = borderedSize - 2
        int borderedSize = heightMap.GetLength(0);

        int meshSimplificationIncrement = levelOfDetail.Equals(0)? 1: levelOfDetail * 2;
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;         //use to calculate topleftX and topLeftZ


        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, useFlatShading);

        //To center the vertices at the center
        float topLeftX = (meshSizeUnsimplified - 1) / -2f;      //do not forget the -1 and the f for -2f to yield a float result
        float topLeftZ = (meshSizeUnsimplified - 1) / 2f;       // positive 2f because the z goes up (-1 0 1 => x = (width - 1)/(-2))

        float floatMeshSize = (float)meshSize;

        float vertexX = 0f;
        float vertexY = 0f;
        float vertexZ = 0f;

        AnimationCurve aHeightCurve = new AnimationCurve(heightCurve.keys);          //a great improvisation over the generation

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = (y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1);
                if (isBorderVertex)
                {
                    vertexIndicesMap [x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap [x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }


        int     vertexIndex;
        Vector3 vertexPosition;
        Vector2 percent;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                vertexIndex = vertexIndicesMap[x, y];
                // tell each vertex where it is in relation to the rest of the map as a percentage for both the x and the y axis
                //it is a percentage between 0 and 1
                percent = new Vector2(
                    (x - meshSimplificationIncrement) / floatMeshSize,
                    (y - meshSimplificationIncrement) / floatMeshSize);

                vertexX        = topLeftX + percent.x * meshSizeUnsimplified;
                vertexY        = aHeightCurve.Evaluate(heightMap [x, y]) * heightMultiplier;
                vertexZ        = topLeftZ - percent.y * meshSizeUnsimplified;          //we don't want to move down from topLeftZ, we move down the y value
                vertexPosition = new Vector3(vertexX, vertexY, vertexZ);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)                  // we ignore the vertices at the most rigth and the most bottom
                {
                    int a = vertexIndicesMap [x, y];
                    int b = vertexIndicesMap [x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap [x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap [x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);                      // first triangle (clock wise on a square)
                    meshData.AddTriangle(d, a, b);                      // second triangle
                }
                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);       //useful to threading instead of returning the mesh, we return the meshData
    }
    public static MeshData GenerateTerrainMesh(float[,] _heightMap, float _heightMultiplier, AnimationCurve _heightCurve, int _levelOfDetail, bool _useFlatShading)
    {
        int meshSimplificationIncrement = (_levelOfDetail == 0) ? 1 : _levelOfDetail * 2;

        // Allows each thread to use the animation curve without locking the thread
        AnimationCurve heightCurve          = new AnimationCurve(_heightCurve.keys);
        int            borderedSize         = _heightMap.GetLength(0);
        int            meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int            meshSizeUnsimplified = borderedSize - 2;

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

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, _useFlatShading);

        int[,] vertextIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1;

                if (isBorderVertex)
                {
                    vertextIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertextIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int vertexIndex = vertextIndicesMap[x, y];

                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = heightCurve.Evaluate(_heightMap[x, y]) * _heightMultiplier;
                Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertextIndicesMap[x, y];
                    int b = vertextIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertextIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertextIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();
        return(meshData);
    }
Exemplo n.º 28
0
    public static MeshData 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;

        MeshData meshData = new MeshData(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);
    }
Exemplo n.º 29
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings settings, int lod)
    {
        int meshSimplificationIncrement = (lod == 0 ? 1 : lod * 2);
        int borderedSize         = heightMap.GetLength(0);
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

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

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;

        MeshData meshData = new MeshData(verticesPerLine, settings.useFlatShading);

        int[,] vertexIndicesMap = new int[borderedSize, borderedSize];
        int meshVertexIndex   = 0;
        int borderVertexIndex = -1;

        // the idea here is that we calculate the border of vertices around the mesh to calculate normals of adjacent meshes
        // each border vertex is less than 0, and will get excluded from the final mesh
        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                bool isBorderVertex = (y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1);

                if (isBorderVertex)
                {
                    vertexIndicesMap[x, y] = borderVertexIndex;
                    borderVertexIndex--;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex++;
                }
            }
        }

        for (int y = 0; y < borderedSize; y += meshSimplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += meshSimplificationIncrement)
            {
                int     vertexIndex    = vertexIndicesMap[x, y];
                Vector2 percent        = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize);
                float   height         = heightMap[x, y];
                Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplified) * settings.meshScale, height, (topLeftZ - percent.y * meshSizeUnsimplified) * settings.meshScale);

                meshData.AddVertex(vertexPosition, percent, vertexIndex);

                // ignore the right and bottom edge vertices of the map
                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + meshSimplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + meshSimplificationIncrement];
                    int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement];

                    meshData.AddTriangle(a, d, c);
                    meshData.AddTriangle(d, a, b);
                }

                vertexIndex++;
            }
        }

        meshData.ProcessMesh();

        return(meshData);
    }