public static MeshDetails BuildMesh(float[,] noiseArea, int lod, AreaDetails areaDetails) { int lodIncrement = lod == 0 ? 1 : lod * 2; int verticesPerLine = areaDetails.verticesPerLine; Vector2 topLeftCorner = new Vector2(-1, 1) * areaDetails.resolution / 2f; MeshDetails meshDetails = new MeshDetails(verticesPerLine, areaDetails.useFlatshading, lodIncrement); int[,] vertexIndexes = new int[verticesPerLine, verticesPerLine]; int meshVertexIndex = 0; int outsideVertexIndex = -1; for (int yIndex = 0; yIndex < verticesPerLine; yIndex++) { for (int xIndex = 0; xIndex < verticesPerLine; xIndex++) { bool isOutsideVertex = yIndex == 0 || xIndex == 0 || yIndex == verticesPerLine - 1 || xIndex == verticesPerLine - 1; bool isUselessVertex = xIndex > 2 && xIndex < verticesPerLine - 3 && yIndex > 2 && yIndex < verticesPerLine - 3 && ((xIndex - 2) % lodIncrement != 0 || (yIndex - 2) % lodIncrement != 0); if (isOutsideVertex) { vertexIndexes[xIndex, yIndex] = outsideVertexIndex; outsideVertexIndex--; } else if (!isUselessVertex) { vertexIndexes[xIndex, yIndex] = meshVertexIndex; meshVertexIndex++; } } } for (int yIndex = 0; yIndex < verticesPerLine; yIndex++) { for (int xIndex = 0; xIndex < verticesPerLine; xIndex++) { bool isUselessVertex = xIndex > 2 && xIndex < verticesPerLine - 3 && yIndex > 2 && yIndex < verticesPerLine - 3 && ((xIndex - 2) % lodIncrement != 0 || (yIndex - 2) % lodIncrement != 0); if (!isUselessVertex) { bool isOutsideVertex = yIndex == 0 || xIndex == 0 || yIndex == verticesPerLine - 1 || xIndex == verticesPerLine - 1; bool isFrontierVertex = (yIndex == 1 || yIndex == verticesPerLine - 2 || xIndex == 1 || xIndex == verticesPerLine - 2) && !isOutsideVertex; bool isMainVertex = (xIndex - 2) % lodIncrement == 0 && (yIndex - 2) % lodIncrement == 0 && !isOutsideVertex && !isFrontierVertex; bool isInsideVertex = (yIndex == 2 || yIndex == verticesPerLine - 3 || xIndex == 2 || xIndex == verticesPerLine - 3) && !isOutsideVertex && !isFrontierVertex && !isMainVertex; int vertexIndex = vertexIndexes[xIndex, yIndex]; Vector2 uv = new Vector2(xIndex - 1, yIndex - 1) / (verticesPerLine - 3); Vector2 vertexCoords = topLeftCorner + new Vector2(uv.x, -uv.y) * areaDetails.resolution; float height = noiseArea[xIndex, yIndex]; if (isInsideVertex) { bool isVertical = xIndex == 2 || xIndex == verticesPerLine - 3; int distanceToMainVertexA = (isVertical ? yIndex - 2 : xIndex - 2) % lodIncrement; int distanceToMainVertexB = lodIncrement - distanceToMainVertexA; float distancePercentage = distanceToMainVertexA / (float)lodIncrement; float heightVertexA = noiseArea[isVertical ? xIndex : xIndex - distanceToMainVertexA, isVertical ? yIndex - distanceToMainVertexA : yIndex]; float heightVertexB = noiseArea[isVertical ? xIndex : xIndex + distanceToMainVertexB, isVertical ? yIndex + distanceToMainVertexB : yIndex]; height = heightVertexA * (1 - distancePercentage) + heightVertexB * distancePercentage; } meshDetails.AddVertex(new Vector3(vertexCoords.x, height, vertexCoords.y), uv, vertexIndex); bool createTriangle = xIndex < verticesPerLine - 1 && yIndex < verticesPerLine - 1 && (!isInsideVertex || (xIndex != 2 && yIndex != 2)); if (createTriangle) { int currentIncrement = (isMainVertex && xIndex != verticesPerLine - 3 && yIndex != verticesPerLine - 3) ? lodIncrement : 1; int vertexAIndex = vertexIndexes[xIndex, yIndex]; int vertexBIndex = vertexIndexes[xIndex + currentIncrement, yIndex]; int vertexCIndex = vertexIndexes[xIndex, yIndex + currentIncrement]; int vertexDIndex = vertexIndexes[xIndex + currentIncrement, yIndex + currentIncrement]; meshDetails.AddTriangle(vertexAIndex, vertexDIndex, vertexCIndex); meshDetails.AddTriangle(vertexDIndex, vertexAIndex, vertexBIndex); } } } } meshDetails.BuildLighting(); return(meshDetails); }