public static TerrainMeshData GenerateFlatMesh(int chunkSize, int levelOfDetail) { float topLeftX = (chunkSize - 1) / -2f; float topLeftZ = (chunkSize - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int verticesPerLine = (chunkSize - 1) / meshSimplificationIncrement + 1; TerrainMeshData meshData = new TerrainMeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < chunkSize; y += meshSimplificationIncrement) { for (int x = 0; x < chunkSize; x += meshSimplificationIncrement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, 0, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)chunkSize, y / (float)chunkSize); if (x < chunkSize - 1 && y < chunkSize - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static TerrainMeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; TerrainMeshData meshData = new TerrainMeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, /*heightCurve.Evaluate(heightMap[x, y])*/ heightMap[x, y] * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static TerrainChunk GenerateTerrainMesh(float[,] heightMap, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; TerrainMeshData MeshData = new TerrainMeshData(verticesPerLine, verticesPerLine); for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { // Add Vertex for this position (index of vertex is width*yPos + xPos) int vertexIndex = MeshData.AddVertex(topLeftX + x, heightMap[x, y], topLeftZ - y); // Add UV (relative position of vertex on the map) MeshData.AddUV(x / (float)width, y / (float)height); // Add the 2 triangles facing down right if we're not at the right or bottom border (because there are no more triangles facing bottom right) // Triangles are constructed clockwise! if (x < width - 1 && y < height - 1) { // Create Triangle that goes from current vertex (i) > vertex below right from current vertext (i+width+1) > vertex below current vertex (i+width) MeshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); // Create Triangle that goes from vertex below right current vertex (i+width+1) > current vertex (i) > vertex right from current vertext (i+1) MeshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } } } return(MeshData.CreateMesh()); }
public static TerrainMeshData GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail) { int skipIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2; int numVertsPerLine = meshSettings.numVertsPerLine; Vector2 topLeft = new Vector2(-1, 1) * meshSettings.meshWorldSize / 2f; TerrainMeshData meshData = new TerrainMeshData(numVertsPerLine, skipIncrement, meshSettings.useFlatShading); int[,] vertexIndicesMap = new int[numVertsPerLine, numVertsPerLine]; int meshVertexIndex = 0; int outOfMeshVertexIndex = -1; for (int y = 0; y < numVertsPerLine; y++) { for (int x = 0; x < numVertsPerLine; x++) { bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1; bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0); if (isOutOfMeshVertex) { vertexIndicesMap [x, y] = outOfMeshVertexIndex; outOfMeshVertexIndex--; } else if (!isSkippedVertex) { vertexIndicesMap [x, y] = meshVertexIndex; meshVertexIndex++; } } } for (int y = 0; y < numVertsPerLine; y++) { for (int x = 0; x < numVertsPerLine; x++) { bool isSkippedVertex = x > 2 && x < numVertsPerLine - 3 && y > 2 && y < numVertsPerLine - 3 && ((x - 2) % skipIncrement != 0 || (y - 2) % skipIncrement != 0); if (!isSkippedVertex) { bool isOutOfMeshVertex = y == 0 || y == numVertsPerLine - 1 || x == 0 || x == numVertsPerLine - 1; bool isMeshEdgeVertex = (y == 1 || y == numVertsPerLine - 2 || x == 1 || x == numVertsPerLine - 2) && !isOutOfMeshVertex; bool isMainVertex = (x - 2) % skipIncrement == 0 && (y - 2) % skipIncrement == 0 && !isOutOfMeshVertex && !isMeshEdgeVertex; bool isEdgeConnectionVertex = (y == 2 || y == numVertsPerLine - 3 || x == 2 || x == numVertsPerLine - 3) && !isOutOfMeshVertex && !isMeshEdgeVertex && !isMainVertex; int vertexIndex = vertexIndicesMap [x, y]; Vector2 percent = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3); Vector2 vertexPosition2D = topLeft + new Vector2(percent.x, -percent.y) * meshSettings.meshWorldSize; float height = heightMap [x, y]; if (isEdgeConnectionVertex) { bool isVertical = x == 2 || x == numVertsPerLine - 3; int dstToMainVertexA = ((isVertical)?y - 2:x - 2) % skipIncrement; int dstToMainVertexB = skipIncrement - dstToMainVertexA; float dstPercentFromAToB = dstToMainVertexA / (float)skipIncrement; float heightMainVertexA = heightMap [(isVertical) ? x : x - dstToMainVertexA, (isVertical) ? y - dstToMainVertexA : y]; float heightMainVertexB = heightMap [(isVertical) ? x : x + dstToMainVertexB, (isVertical) ? y + dstToMainVertexB : y]; height = heightMainVertexA * (1 - dstPercentFromAToB) + heightMainVertexB * dstPercentFromAToB; } meshData.AddVertex(new Vector3(vertexPosition2D.x, height, vertexPosition2D.y), percent, vertexIndex); bool createTriangle = x < numVertsPerLine - 1 && y < numVertsPerLine - 1 && (!isEdgeConnectionVertex || (x != 2 && y != 2)); if (createTriangle) { int currentIncrement = (isMainVertex && x != numVertsPerLine - 3 && y != numVertsPerLine - 3) ? skipIncrement : 1; int a = vertexIndicesMap [x, y]; int b = vertexIndicesMap [x + currentIncrement, y]; int c = vertexIndicesMap [x, y + currentIncrement]; int d = vertexIndicesMap [x + currentIncrement, y + currentIncrement]; meshData.AddTriangle(a, d, c); meshData.AddTriangle(d, a, b); } } } } meshData.ProcessMesh(); return(meshData); }