/// <summary>
    /// 划分格子的Lod级别
    /// </summary>
    private void UpdateLodLevel()
    {
        var     cam = Camera.main;
        float   CL  = 0.6f;
        Vector3 pos = hero.position;

        for (int i = 0; i < PieceNum; i++)
        {
            for (int j = 0; j < PieceNum; j++)
            {
                LodPiece ps       = m_piecees[j, i];
                Vector2  center   = ps.box.position + ps.box.size / 2;
                float    distence = Vector2.Distance(center, new Vector2(pos.x, pos.z));
                ps.LodLevel = Mathf.FloorToInt((distence / ps.box.width) * CL);
                if (ps.LodLevel > LOD_LEVEL_MAX)
                {
                    ps.LodLevel = LOD_LEVEL_MAX;
                }
            }
        }
        for (int i = 0; i < PieceNum; i++)
        {
            for (int j = 0; j < PieceNum; j++)
            {
                LodPiece ps = m_piecees[j, i];
                CheckSideLodLevel(j, i, ps);
            }
        }
    }
Ejemplo n.º 2
0
 /// <summary>
 /// 检查所有的片的LOD级别是否符合规范
 /// </summary>
 public void CheckSidesLodLevel()
 {
     for (int i = 0; i < m_mesh_piece_num; i++)
     {
         for (int j = 0; j < m_mesh_piece_num; j++)
         {
             LodPiece ps = m_piecees[j, i];
             CheckSideLodLevel(j, i, ps);
         }
     }
 }
Ejemplo n.º 3
0
    /// <summary>
    /// 初始化片的数据
    /// </summary>
    private void InitPiece()
    {
        if (m_piecees == null)
        {
            m_piecees = new LodPiece[m_mesh_piece_num, m_mesh_piece_num];
        }
        Vector2 piecesize = m_mesh_segment_size * m_mesh_piece_segment;

        for (int i = 0; i < m_mesh_piece_num; i++)
        {
            for (int j = 0; j < m_mesh_piece_num; j++)
            {
                LodPiece piece = m_piecees[j, i];
                if (piece == null)
                {
                    piece           = new LodPiece();
                    m_piecees[j, i] = piece;
                }
                int offset_x = j * m_mesh_piece_segment;
                int offset_y = i * m_mesh_piece_segment;
                piece.offset_x = offset_x;
                piece.offset_y = offset_y;
                piece.LodLevel = ChunkManager.LOD_LEVEL_MAX;
                piece.box      = new Rect(offset_x * m_mesh_segment_size.x + box.x, offset_y * m_mesh_segment_size.y + box.y, piecesize.x, piecesize.y);
            }
        }
        var cache_v3  = ChunkManager.Instence.cache_v3;
        var cache_v2  = ChunkManager.Instence.cache_v2;
        var cache_int = ChunkManager.Instence.cache_int;

        for (int i = 0; i < m_mesh_piece_num; i++)
        {//需要分2次循环执行,否则LookUpSideLodLevel会出错
            for (int j = 0; j < m_mesh_piece_num; j++)
            {
                bool[]    isLevelBiger = new bool[] { false, false, false, false };
                LodPiece  piece        = m_piecees[j, i];
                int       each_offset  = 1 << piece.LodLevel;
                int       segment      = m_mesh_piece_segment / each_offset;
                int       ver_num      = (segment + 1) * (segment + 1);
                Vector3[] vers         = cache_v3.GetOneArray(ver_num);
                Vector3[] nors         = cache_v3.GetOneArray(ver_num);
                Vector2[] uvs          = cache_v2.GetOneArray(ver_num);
                int[]     indexes      = cache_int.GetOneArray(segment * segment * 6);
                LookUpSideLodLevel(j, i, piece.LodLevel, isLevelBiger);
                UpdatePieceLod(vers, nors, uvs, indexes, segment, piece, isLevelBiger);
                piece.vers                = vers;
                piece.nors                = nors;
                piece.uvs                 = uvs;
                piece.indexes             = indexes;
                piece.last_lod_level      = piece.LodLevel;
                piece.last_is_biger_level = isLevelBiger;
            }
        }
    }
Ejemplo n.º 4
0
    /// <summary>
    /// 创建所有的片
    /// </summary>
    private void CreatePieces()
    {
        GameObject piece_root = new GameObject("chunk_" + id_x + "_" + id_y);

        obj = piece_root;
        for (int i = 0; i < m_mesh_piece_num; i++)
        {
            for (int j = 0; j < m_mesh_piece_num; j++)
            {
                LodPiece   piece = m_piecees[j, i];
                GameObject obj   = MeshCreator.DrawMesh(piece.vers, piece.nors, piece.uvs, piece.indexes, m_chunk_mat, "piece_" + j + "_" + i);
                piece.mesh = obj.GetComponent <MeshFilter>().mesh;
                obj.AddComponent <MeshCollider>();
                obj.transform.SetParent(piece_root.transform);
            }
        }
        piece_root.transform.SetParent(ChunkManager.Instence.transform);
    }
Ejemplo n.º 5
0
 /// <summary>
 /// 检查周围4个格子的Lod级别是否符合:Lod级别不超过此格子的级别+1。否则,直接强制划分Lod级别,并递归划分
 /// </summary>
 /// <param name="j"></param>
 /// <param name="i"></param>
 /// <param name="ps"></param>
 private void CheckSideLodLevel(int j, int i, LodPiece ps)
 {
     if (j > 0 && m_piecees[j - 1, i].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j - 1, i].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j - 1, i, m_piecees[j - 1, i]);
     }
     if (j < m_mesh_piece_num - 1 && m_piecees[j + 1, i].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j + 1, i].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j + 1, i, m_piecees[j + 1, i]);
     }
     if (i > 0 && m_piecees[j, i - 1].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j, i - 1].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j, i - 1, m_piecees[j, i - 1]);
     }
     if (i < m_mesh_piece_num - 1 && m_piecees[j, i + 1].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j, i + 1].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j, i + 1, m_piecees[j, i + 1]);
     }
     if (j == 0 && Left != null && Left.m_piecees[m_mesh_piece_num - 1, i].LodLevel - ps.LodLevel > 1)
     {
         Left.m_piecees[m_mesh_piece_num - 1, i].LodLevel = ps.LodLevel + 1;
         Left.CheckSideLodLevel(m_mesh_piece_num - 1, i, Left.m_piecees[m_mesh_piece_num - 1, i]);
     }
     if (j == m_mesh_piece_num - 1 && Right != null && Right.m_piecees[0, i].LodLevel - ps.LodLevel > 1)
     {
         Right.m_piecees[0, i].LodLevel = ps.LodLevel + 1;
         Right.CheckSideLodLevel(0, i, Right.m_piecees[0, i]);
     }
     if (i == 0 && Down != null && Down.m_piecees[j, m_mesh_piece_num - 1].LodLevel - ps.LodLevel > 1)
     {
         Down.m_piecees[j, m_mesh_piece_num - 1].LodLevel = ps.LodLevel + 1;
         Down.CheckSideLodLevel(j, m_mesh_piece_num - 1, Down.m_piecees[j, m_mesh_piece_num - 1]);
     }
     if (i == m_mesh_piece_num - 1 && Up != null && Up.m_piecees[j, 0].LodLevel - ps.LodLevel > 1)
     {
         Up.m_piecees[j, 0].LodLevel = ps.LodLevel + 1;
         Up.CheckSideLodLevel(j, 0, Up.m_piecees[j, 0]);
     }
 }
Ejemplo n.º 6
0
    /// <summary>
    /// 划分格子的Lod级别
    /// </summary>
    public void UpdateLodLevel(Vector3 pos)
    {
        var cl = ChunkManager.Instence.CL;

        for (int i = 0; i < m_mesh_piece_num; i++)
        {
            for (int j = 0; j < m_mesh_piece_num; j++)
            {
                LodPiece ps       = m_piecees[j, i];
                Vector2  center   = ps.box.position + ps.box.size / 2;
                float    distence = Vector2.Distance(center, new Vector2(pos.x, pos.z));
                ps.LodLevel = Mathf.FloorToInt((distence / ps.box.width) * cl);
                if (ps.LodLevel > ChunkManager.LOD_LEVEL_MAX)
                {
                    ps.LodLevel = ChunkManager.LOD_LEVEL_MAX;
                }
            }
        }
    }
Ejemplo n.º 7
0
    private bool isNormalUpdated = false;   //是否更新过法线

    /// <summary>
    /// 销毁根GameObject和材质
    /// </summary>
    public void DestroyGameObject()
    {
        if (m_piecees != null)
        {
            var cache_v3  = ChunkManager.Instence.cache_v3;
            var cache_V2  = ChunkManager.Instence.cache_v2;
            var cache_int = ChunkManager.Instence.cache_int;
            for (int i = 0; i < m_mesh_piece_num; i++)
            {
                for (int j = 0; j < m_mesh_piece_num; j++)
                {
                    LodPiece ps = m_piecees[j, i];
                    cache_v3.GiveBack(ps.vers);
                    cache_v3.GiveBack(ps.nors);
                    cache_V2.GiveBack(ps.uvs);
                    cache_int.GiveBack(ps.indexes);
                    ps.vers    = null;
                    ps.nors    = null;
                    ps.uvs     = null;
                    ps.indexes = null;
                    ps.mesh    = null;
                }
            }
        }
        if (obj != null)
        {
            GameObject.Destroy(obj);
            obj = null;
        }
        if (m_chunk_mat != null)
        {
            Object.Destroy(m_chunk_mat);
            m_chunk_mat = null;
        }
        if (mask != null)
        {
            Object.Destroy(mask);
            mask      = null;
            maskcolor = null;
        }
    }
 /// <summary>
 /// 检查周围4个格子的Lod级别是否符合:Lod级别不超过此格子的级别+1,这个条件。否则,直接强制划分Lod级别,并递归划分
 /// </summary>
 /// <param name="j"></param>
 /// <param name="i"></param>
 /// <param name="ps"></param>
 private void CheckSideLodLevel(int j, int i, LodPiece ps)
 {
     if (j > 0 && m_piecees[j - 1, i].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j - 1, i].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j - 1, i, m_piecees[j - 1, i]);
     }
     if (j < PieceNum - 1 && m_piecees[j + 1, i].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j + 1, i].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j + 1, i, m_piecees[j + 1, i]);
     }
     if (i > 0 && m_piecees[j, i - 1].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j, i - 1].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j, i - 1, m_piecees[j, i - 1]);
     }
     if (i < PieceNum - 1 && m_piecees[j, i + 1].LodLevel - ps.LodLevel > 1)
     {
         m_piecees[j, i + 1].LodLevel = ps.LodLevel + 1;
         CheckSideLodLevel(j, i + 1, m_piecees[j, i + 1]);
     }
 }
Ejemplo n.º 9
0
    /// <summary>
    /// 更新所有片的网格
    /// </summary>
    public void UpdateLod()
    {
        var m_cache_v3  = ChunkManager.Instence.cache_v3;
        var m_cache_v2  = ChunkManager.Instence.cache_v2;
        var m_cache_int = ChunkManager.Instence.cache_int;

        bool[] isLevelBiger = new bool[4];
        for (int i = 0; i < m_mesh_piece_num; i++)
        {
            for (int j = 0; j < m_mesh_piece_num; j++)
            {
                LodPiece piece = m_piecees[j, i];
                LookUpSideLodLevel(j, i, piece.LodLevel, isLevelBiger);
                if (isNormalUpdated || piece.CheckNeedUpdate(isLevelBiger))
                {
                    piece.SetLastBigLevel(isLevelBiger);
                    int each_offset = 1 << piece.LodLevel;
                    int segment     = m_mesh_piece_segment / each_offset;
                    int ver_num     = (segment + 1) * (segment + 1);
                    if (ver_num != piece.vers.Length)
                    {
                        m_cache_v3.GiveBack(piece.vers);
                        piece.vers = m_cache_v3.GetOneArray(ver_num);
                        m_cache_v3.GiveBack(piece.nors);
                        piece.nors = m_cache_v3.GetOneArray(ver_num);
                        m_cache_v2.GiveBack(piece.uvs);
                        piece.uvs = m_cache_v2.GetOneArray(ver_num);
                        m_cache_int.GiveBack(piece.indexes);
                        piece.indexes = m_cache_int.GetOneArray(segment * segment * 6);
                    }
                    UpdatePieceLod(piece.vers, piece.nors, piece.uvs, piece.indexes, segment, piece, isLevelBiger);
                    piece.UpdateMeshData();
                }
            }
        }
        isNormalUpdated = false;
    }
 private void UpdateLod()
 {
     bool[] isLevelBiger = new bool[4];
     for (int i = 0; i < PieceNum; i++)
     {
         for (int j = 0; j < PieceNum; j++)
         {
             LodPiece piece = m_piecees[j, i];
             LookUpSideLodLevel(j, i, piece.LodLevel, isLevelBiger);
             if (piece.CheckNeedUpdate(isLevelBiger))
             {
                 int each_offset = 1 << piece.LodLevel;
                 int segment     = PieceMechSegment / each_offset;
                 int ver_num     = (segment + 1) * (segment + 1);
                 if (ver_num != piece.vers.Length)
                 {
                     m_cache_v3.GiveBack(piece.vers);
                     piece.vers = m_cache_v3.GetOneArray(ver_num);
                     m_cache_v3.GiveBack(piece.nors);
                     piece.nors = m_cache_v3.GetOneArray(ver_num);
                     m_cache_v2.GiveBack(piece.uvs);
                     piece.uvs = m_cache_v2.GetOneArray(ver_num);
                     m_cache_int.GiveBack(piece.indexes);
                     piece.indexes = m_cache_int.GetOneArray(segment * segment * 6);
                 }
                 UpdatePieceLod(piece.vers, piece.nors, piece.uvs, piece.indexes, segment, piece, isLevelBiger);
                 var mesh = piece.mesh;
                 mesh.Clear();
                 mesh.vertices  = piece.vers;
                 mesh.uv        = piece.uvs;
                 mesh.triangles = piece.indexes;
                 mesh.normals   = piece.nors;
             }
         }
     }
 }
    private GameObject CreatePiece(LodPiece piece, string name)
    {
        int each_offset = 1 << piece.LodLevel;
        int segment     = PieceMechSegment / each_offset;
        int ver_num     = (segment + 1) * (segment + 1);

        bool[]    isLevelBiger = new bool[] { false, false, false, false };
        Vector3[] vers         = new Vector3[ver_num];
        Vector3[] nors         = new Vector3[ver_num];
        Vector2[] uvs          = new Vector2[ver_num];
        int[]     indexes      = new int[segment * segment * 6];
        UpdatePieceLod(vers, nors, uvs, indexes, segment, piece, isLevelBiger);
        GameObject obj = MeshCreator.DrawMesh(vers, nors, uvs, indexes, PieceMat, name);

        piece.mesh                = obj.GetComponent <MeshFilter>().mesh;
        piece.vers                = vers;
        piece.nors                = nors;
        piece.uvs                 = uvs;
        piece.indexes             = indexes;
        piece.last_lod_level      = piece.LodLevel;
        piece.last_is_biger_level = isLevelBiger;
        obj.AddComponent <MeshCollider>();
        return(obj);
    }
    private void InitPiece()
    {//test
        GameObject piece_root = new GameObject("piece_root");

        m_piecees = new LodPiece[PieceNum, PieceNum];
        for (int i = 0; i < PieceNum; i++)
        {
            for (int j = 0; j < PieceNum; j++)
            {
                int      offset_x = j * PieceMechSegment;
                int      offset_y = i * PieceMechSegment;
                LodPiece piece    = new LodPiece()
                {
                    offset_x = offset_x,
                    offset_y = offset_y,
                    LodLevel = LOD_LEVEL_MAX,
                    box      = new Rect(offset_x * m_mesh_segment_size.x, offset_y * m_mesh_segment_size.y, PieceMechSegment * m_mesh_segment_size.x, PieceMechSegment * m_mesh_segment_size.y)
                };
                m_piecees[j, i] = piece;
                GameObject obj = CreatePiece(piece, "piece_" + j + "_" + i);
                obj.transform.SetParent(piece_root.transform);
            }
        }
    }
    private void UpdatePieceLod(Vector3[] vers, Vector3[] nors, Vector2[] uvs, int[] indexes, int segment, LodPiece piece, bool[] isLevelBiger)
    {
        int each_offset = 1 << piece.LodLevel;

        for (int i = 0; i < segment + 1; i++)
        {
            for (int j = 0; j < segment + 1; j++)
            {
                int index_x = piece.offset_x + each_offset * j;
                int index_y = piece.offset_y + each_offset * i;
                int index   = i * (segment + 1) + j;
                vers[index] = m_mesh_vers[index_x, index_y];
                nors[index] = m_mesh_normals[index_x, index_y];
                uvs[index]  = m_mesh_uvs[index_x, index_y];
            }
        }
        InitPieceIndexes(segment, indexes, isLevelBiger);
    }