public void SetNeighbor(QuadTreeMeshNode left, QuadTreeMeshNode right, QuadTreeMeshNode up, QuadTreeMeshNode down) { m_IsLeftEdge = left != null && left.isEdge && (left.m_RightBottomChild.isEdge || left.m_RightTopChild.isEdge); m_IsRightEdge = right != null && right.isEdge && (right.m_LeftBottomChild.isEdge || right.m_LeftTopChild.isEdge); m_IsUpEdge = up != null && up.isEdge && (up.m_RightBottomChild.isEdge || up.m_LeftBottomChild.isEdge); m_IsDownEdge = down != null && down.isEdge && (down.m_LeftTopChild.isEdge || down.m_RightTopChild.isEdge); if (m_IsLeftEdge || m_IsRightEdge || m_IsUpEdge || m_IsDownEdge) { isEdge = true; } //if (left != 0 || right != 0 || up != 0 || down != 0) // combinelod += 1; }
public QuadTreeMeshNode(QuadTreeMeshNode leftTop, QuadTreeMeshNode leftBottom, QuadTreeMeshNode rightTop, QuadTreeMeshNode rightBottom, float offsetX, float offsetY, int cellX, int cellY, float cellWidth, float cellHeight) : this(offsetX, offsetY, cellX, cellY, cellWidth, cellHeight) { if (leftTop.isEdge || leftBottom.isEdge || rightTop.isEdge || rightBottom.isEdge) { this.isEdge = true; } else { this.isEdge = false; } m_LeftBottomChild = leftBottom; m_LeftTopChild = leftTop; m_RightBottomChild = rightBottom; m_RightTopChild = rightTop; }
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)); }