示例#1
0
        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);
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }