public Mesh GenerateMesh(Texture2D texture) { if (cellSizeX <= 0 || cellSizeZ <= 0 || widthX <= 0 || widthZ <= 0) { return(null); } float deltaX = widthX * 2 / cellSizeX; float deltaY = widthZ * 2 / cellSizeZ; MeshVertexData cache = new MeshVertexData(cellSizeX, cellSizeZ, deltaX, deltaY, -widthX, -widthZ); for (int i = 0; i < cellSizeZ; i++) { for (int j = 0; j < cellSizeX; j++) { Vector3 p0 = new Vector3(-widthX + j * deltaX, 0, -widthZ + i * deltaY); Vector3 p1 = new Vector3(-widthX + j * deltaX, 0, -widthZ + i * deltaY + deltaY); Vector3 p2 = new Vector3(-widthX + j * deltaX + deltaX, 0, -widthZ + i * deltaY + deltaY); Vector3 p3 = new Vector3(-widthX + j * deltaX + deltaX, 0, -widthZ + i * deltaY); cache.AddVertex(p0); cache.AddVertex(p1); cache.AddVertex(p2); cache.AddVertex(p3); cache.AddIndex(cache.index); cache.AddIndex(cache.index + 1); cache.AddIndex(cache.index + 2); cache.AddIndex(cache.index); cache.AddIndex(cache.index + 2); cache.AddIndex(cache.index + 3); cache.index += 4; } } Mesh mesh = cache.Apply(texture, uvDir, samples); return(mesh); }
public Mesh GenerateMesh(Texture2D texture) { int cellSize = (int)Mathf.Pow(2, depth); if (widthX <= 0 || widthZ <= 0 || samples < 1) { return(null); } QuadTreeMeshNode[,] cells = new QuadTreeMeshNode[cellSize, cellSize]; //根据贴图尺寸和单元格数量,计算分配给单个单元格的像素宽高 int w = texture.width / cellSize; int h = texture.height / cellSize; //计算Lod for (int i = 0; i < cellSize; i++) { for (int j = 0; j < cellSize; j++) { var cell = new QuadTreeMeshLeaf(-widthX, -widthZ, i, j, widthX * 2 / cellSize, widthZ * 2 / cellSize); //为单元格分配指定区域的像素并计算极差和平均值 cell.Calculate(texture, i * w, j * h, w, h); cells[i, j] = cell; } } float dtx = widthX * 2 / cellSize; float dty = widthZ * 2 / cellSize; MeshVertexData cache = new MeshVertexData(cellSize, cellSize, dtx, dty, -widthX, -widthZ); while (cellSize > 1) { cellSize = cellSize / 2; QuadTreeMeshNode[,] nodes = new QuadTreeMeshNode[cellSize, cellSize]; for (int i = 0; i < cellSize; i++) { for (int j = 0; j < cellSize; j++) { QuadTreeMeshNode lb = cells[i * 2, j * 2]; QuadTreeMeshNode rb = cells[i * 2 + 1, j * 2]; QuadTreeMeshNode lt = cells[i * 2, j * 2 + 1]; QuadTreeMeshNode rt = cells[i * 2 + 1, j * 2 + 1]; QuadTreeMeshNode node = new QuadTreeMeshNode(lt, lb, rt, rb, -widthX, -widthZ, i, j, widthX * 2 / cellSize, widthZ * 2 / cellSize); nodes[i, j] = node; } } for (int i = 0; i < cellSize; i++) { for (int j = 0; j < cellSize; j++) { var left = i != 0 ? nodes[i - 1, j] : null; var right = i != nodes.GetLength(0) - 1 ? nodes[i + 1, j] : null; var down = j != 0 ? nodes[i, j - 1] : null; var up = j != nodes.GetLength(1) - 1 ? nodes[i, j + 1] : null; nodes[i, j].SetNeighbor(left, right, up, down); } } cells = nodes; } for (int i = 0; i < cellSize; i++) { for (int j = 0; j < cellSize; j++) { cells[i, j].UpdateMesh(cache); } } return(cache.Apply(texture, uvDir, samples)); }
public Mesh GenerateMesh(Texture2D texture) { if (cellSizeX <= 0 || cellSizeZ <= 0 || widthX <= 0 || widthZ <= 0 || maxLod < 0 || samples < 1) { return(null); } LodMeshCell[,] cells = new LodMeshCell[cellSizeX, cellSizeZ]; //根据贴图尺寸和单元格数量,计算分配给单个单元格的像素宽高 int w = texture.width / cellSizeX; int h = texture.height / cellSizeZ; //计算Lod for (int i = 0; i < cellSizeX; i++) { for (int j = 0; j < cellSizeZ; j++) { cells[i, j] = new LodMeshCell(-widthX, -widthZ, i, j, widthX * 2 / cellSizeX, widthZ * 2 / cellSizeZ); //为单元格分配指定区域的像素并计算极差和平均值 cells[i, j].Calculate(texture, i * w, j * h, w, h, maxLod); } } //根据上一步计算的结果,将最大lod单元格边上的格子设置lod递减 for (int i = 0; i < cellSizeX; i++) { for (int j = 0; j < cellSizeZ; j++) { LodMeshCell cell = cells[i, j]; if (cell.lod == -1) { continue; } if (cell.lod != maxLod) { continue; } for (int lx = maxLod - 1, ly = 0; lx >= 0; lx--, ly++) { for (int lk = 0; lk <= ly; lk++) { if (lk == 0 && lx == 0) { continue; } int clod = maxLod - lx - lk; //从最大lod处往外递减lod SetNeighborLOD(i - lx, j - lk, cellSizeX, cellSizeZ, clod, cells); SetNeighborLOD(i + lx, j - lk, cellSizeX, cellSizeZ, clod, cells); SetNeighborLOD(i - lx, j + lk, cellSizeX, cellSizeZ, clod, cells); SetNeighborLOD(i + lx, j + lk, cellSizeX, cellSizeZ, clod, cells); } } } } //根据Lod生成Mesh float p = Mathf.Pow(2, maxLod); float dtx = widthX * 2 / cellSizeX / p; float dty = widthZ * 2 / cellSizeZ / p; MeshVertexData cache = new MeshVertexData(cellSizeX * (int)p, cellSizeZ * (int)p, dtx, dty, -widthX, -widthZ); for (int i = 0; i < cellSizeX; i++) { for (int j = 0; j < cellSizeZ; j++) { LodMeshCell cell = cells[i, j]; if (cell.lod == -1) { continue; } int leftLod = i == 0 ? -1 : cells[i - 1, j].lod; int rightLod = i == cells.GetLength(0) - 1 ? -1 : cells[i + 1, j].lod; int downLod = j == 0 ? -1 : cells[i, j - 1].lod; int upLod = j == cells.GetLength(1) - 1 ? -1 : cells[i, j + 1].lod; cell.SetNeighborLOD(leftLod, rightLod, upLod, downLod); cell.UpdateMesh(cache); } } //生成网格 Mesh mesh = cache.Apply(texture, uvDir, samples); return(mesh); }