BakeNormals() public method

public BakeNormals ( ) : void
return void
Ejemplo n.º 1
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, int levelOfDetail,
                                               float heightMultiplier, AnimationCurve heightCurve)
    {
        var   localHeightCurve = 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 meshSimplificationIncrement = (int)Mathf.Pow(2, levelOfDetail);
        int verticesPerLine             = (width - 1) / meshSimplificationIncrement + 1;

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

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

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

                vertexIndex++;
            }
        }

        meshData.BakeNormals();

        return(meshData);
    }
Ejemplo n.º 2
0
    MeshData GenerateMesh(float[,] heightMap, int lod)
    {
        int            width    = heightMap.GetLength(0);
        int            height   = heightMap.GetLength(1);
        AnimationCurve curve    = new AnimationCurve(elevationCurve.keys);
        float          topLeftX = (width - 1) / -2.0f;
        float          topLeftZ = (height - 1) / 2.0f;
        int            meshSimplificationLevel = (lod == 0)? 1 : lod * 2;
        int            verticesPerLine         = (width - 1) / meshSimplificationLevel + 1;
        MeshData       meshData    = new MeshData(verticesPerLine, verticesPerLine);
        int            vertexIndex = 0;

        for (int y = 0; y < height; y += meshSimplificationLevel)
        {
            for (int x = 0; x < width; x += meshSimplificationLevel)
            {
                meshData.vertices[vertexIndex] =
                    new Vector3(topLeftX + x,
                                elevation * curve.Evaluate(heightMap[x, y]),
                                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++;
            }
        }
        meshData.BakeNormals();
        return(meshData);
    }
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail)
    {
        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);

        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.BakeNormals();

        return(meshData);
    }
Ejemplo n.º 4
0
    /*
     *   -1  -2  -3  -4  -5
     *    o   o   o   o   o
     *   -6   0   1   2  -7
     *    o   #   #   #   o
     *   -8   3   4   5  -9
     *    o   #   #   #   o
     *  -10   6   7   8  -11
     *    o   #   #   #   o
     *  -12  -13 -14 -15 -16
     *    o   o   o   o   o
     */
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightFactor, AnimationCurve _heightCurve, int levelOfDetail)
    {
        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);

        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     -= 1;
                }
                else
                {
                    vertexIndicesMap[x, y] = meshVertexIndex;
                    meshVertexIndex       += 1;
                }
            }
        }

        // see for details : https://www.youtube.com/watch?v=4RpVBYW1r5M
        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]) * heightFactor;
                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)
                {
                    /*
                     *
                     * (x;y)
                     *  /
                     * a    b (x+i; y)
                     * o ___o
                     * |\\  |  triangle adc
                     * | \\ |  triangle dab
                     * |__\\|
                     * o    o
                     * c    d (x+i;y+i)
                     *  \
                     * (x;y+i)
                     *
                     */
                    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.BakeNormals();

        return(meshData);
    }
Ejemplo n.º 5
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail)
    {
        //Used to simplify mesh triangles on distance
        int skipIncrement   = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; // If levelofdetail is 0 set it to 1 otherwise double
        int numVertsPerLine = meshSettings.NumVertsPerLine;

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

        MeshData meshData = new MeshData(numVertsPerLine, skipIncrement); //Uses data for threading

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

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

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

                    vertexIndex++;
                }
            }
        }

        meshData.BakeNormals();

        return(meshData);
    }
    public static MeshData FromHeightMap(int seed, MeshSettings settings, float[,] heightMap, int levelOfDetail)
    {
        Random.State initialState = Random.state;
        Random.InitState(seed);

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

        #region Border Array

        #region Variables

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

        #endregion

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

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

        #endregion

        #region Mesh Data

        #region Variables

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

        int     vertexIndex;
        Vector2 uvPercent;
        Vector3 vertexPosition;

        #endregion

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

                uvPercent = new Vector2(
                    (x - meshSimplificationIncrement) / (float)meshSize,
                    (z - meshSimplificationIncrement) / (float)meshSize
                    );

                vertexPosition = new Vector3(
                    (topLeftX + uvPercent.x * meshSizeUnsimplified) * settings.scale,
                    heightMap[x, z],
                    (topLeftZ - uvPercent.y * meshSizeUnsimplified) * settings.scale
                    );

                meshData.AddVertex(vertexPosition, uvPercent, vertexIndex);

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

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

                vertexIndex++;
            }
        }

        #endregion

        meshData.BakeNormals();
        Random.state = initialState;
        return(meshData);
    }
Ejemplo n.º 7
0
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier,
                                               AnimationCurve heightCurve, int levelOfDetail)
    {
        //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);

        //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.BakeNormals();

        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)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);             // makes water flat

        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; // changes resolution parameter

        int borderedSize         = heightMap.GetLength(0);                              // make a border to make the terrain seamless across chunks
        int meshSize             = borderedSize - 2 * meshSimplificationIncrement;
        int meshSizeUnsimplified = borderedSize - 2;

        float topLeftX = (meshSizeUnsimplified - 1) / -2f;         // index for top left corner
        float topLeftZ = (meshSizeUnsimplified - 1) / 2f;

        int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1;         // how many vertices should be created

        MeshData meshData = new MeshData(verticesPerLine);

        int [,] vertexIndicesMap = new int [borderedSize, borderedSize];         // keeps track of vertex info before creating the mesh data
        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--;                     // make border vertices negative to differentiate them from internal vertices
                }
                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.BakeNormals();

        return(meshData);
    }
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, int chunkIndex)
    {
        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);

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

        int     numVertsPerLine = supportedChunkSizes[chunkIndex] + 5;
        int     meshWorldSize   = numVertsPerLine - 3;
        Vector2 topLeft         = new Vector2(-1, 1) * meshWorldSize / 2f;

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

        MeshData meshData = new MeshData(numVertsPerLine, skipIncriment);

        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) % skipIncriment != 0 || (y - 2) % skipIncriment != 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) % skipIncriment != 0 || (y - 2) % skipIncriment != 0);
                if (!isSkippedVertex)
                {
                    bool isOutOfMeshVertex      = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1;
                    bool isMeshEdgeVertex       = (y == 1 || x == 1 || y == numVertsPerLine - 2 || x == numVertsPerLine - 2) && !isOutOfMeshVertex;
                    bool isMainVertex           = ((x - 2) % skipIncriment == 0 && (y - 2) % skipIncriment == 0) && !isOutOfMeshVertex && !isMeshEdgeVertex;
                    bool isEdgeConnectionVertex = (y == 2 || y == numVertsPerLine - 3 || x == 2 || x == numVertsPerLine - 3) && !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) * meshWorldSize;

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

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

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

                        height = heightMainVertexA * (1 - dstPercentFromAToB) + heightMainVertexB * dstPercentFromAToB;
                    }
                    else if (isMainVertex)
                    {
                        meshData.addMainVertex(new Vector3(vertexPosition2D.x, height, vertexPosition2D.y), mainVertexIndex);
                        mainVertexIndex++;
                    }

                    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 currentIncriment = (isMainVertex && x != numVertsPerLine - 3 && y != numVertsPerLine - 3) ? skipIncriment : 1;
                        int a = vertexIndicesMap[x, y];
                        int b = vertexIndicesMap[x + currentIncriment, y];
                        int c = vertexIndicesMap[x, y + currentIncriment];
                        int d = vertexIndicesMap[x + currentIncriment, y + currentIncriment];
                        meshData.AddTriangle(a, d, c);
                        meshData.AddTriangle(d, a, b);
                    }
                }
            }
        }

        meshData.BakeNormals();
        return(meshData);
    }
	public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) {
		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);

		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.BakeNormals ();

		return meshData;

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

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

        var meshData = new MeshData(numVertsPerLine, skipIncrement);

        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 ax = isVertical ? x : x - dstToMainVertexA;
                        var ay = isVertical ? y - dstToMainVertexA : y;
                        var bx = isVertical ? x : x + dstToMainVertexB;
                        var by = isVertical ? y + dstToMainVertexB : y;

                        var heightMainVertexA = heightMap[ax, ay];
                        var heightMainVertexB = heightMap[bx, by];

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

                        var indexA = vertexIndicesMap[ax, ay];
                        var indexB = vertexIndicesMap[bx, by];
                        meshData.AddAveragedNormal(vertexIndex, indexA, indexB, dstPercentFromAToB);
                    }

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

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

                    if (createTrianlge)
                    {
                        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.BakeNormals();

        return(meshData);
    }
Ejemplo n.º 12
0
    public static MeshData generateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve meshHeightCurve, int levelDetail)
    {
        AnimationCurve reference = new AnimationCurve(meshHeightCurve.keys);
        int            simplificationIncrement = (levelDetail == 0 ? 1 : levelDetail * 2);
        int            borderedSize            = heightMap.GetLength(0);
        //int borderedSize = heightMap.GetLength(1);
        int meshSize             = borderedSize - 2 * simplificationIncrement;
        int meshSizeUnsimplifies = borderedSize - 2;

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

        /*these two variables help the map spawns in the middle*/
        float topLeftX = (meshSizeUnsimplifies - 1) / -2f;
        float topLeftZ = (meshSizeUnsimplifies - 1) / 2f;

        MeshData meshData = new MeshData(verticesPerLine);

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

        //int vertexIndex = 0;

        for (int y = 0; y < borderedSize; y += simplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += simplificationIncrement)
            {
                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 += simplificationIncrement)
        {
            for (int x = 0; x < borderedSize; x += simplificationIncrement)
            {
                int vertexIndex = vertexIndicesMap[x, y];

                Vector2 percent        = new Vector2((x - simplificationIncrement) / (float)meshSize, (y - simplificationIncrement) / (float)meshSize);
                float   height         = reference.Evaluate(heightMap[x, y]) * heightMultiplier;//this defines the height of all vertices
                Vector3 vertexPosition = new Vector3((topLeftX + percent.x * meshSizeUnsimplifies), height, (topLeftZ - percent.y * meshSizeUnsimplifies));

                meshData.addVertex(vertexPosition, percent, vertexIndex);
                if (x < borderedSize - 1 && y < borderedSize - 1)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + simplificationIncrement, y];
                    int c = vertexIndicesMap[x, y + simplificationIncrement];
                    int d = vertexIndicesMap[x + simplificationIncrement, y + simplificationIncrement];

                    meshData.addTriangles(a, d, c);
                    meshData.addTriangles(d, a, b);
                }
                ; //vertexIndex++;
            }
        }
        meshData.BakeNormals();
        //return meshData for multi-threading so the game doesn't freeze when it loads
        //**we can't create Mesh inside the thread, so you have to do it outside the threading method
        return(meshData);
    }