public bool IsChunkRendering(int index)
    {
        int x = RSubTerrUtils.IndexToChunkX(index);
        int z = RSubTerrUtils.IndexToChunkZ(index);

        return(m_TerrainRegion.Contains(new Vector3((x + 0.5f) * RSubTerrConstant.ChunkSizeF, 1, (z + 0.5f) * RSubTerrConstant.ChunkSizeF)));
    }
    public void SyncChunksData()
    {
        bool can_read = Monitor.TryEnter(VFDataRTGen.s_dicTreeInfoList);

        if (can_read)
        {
            // Add trees
            _lstChnkIdxActive.Clear();
            foreach (KeyValuePair <IntVector2, List <TreeInfo> > kvp in VFDataRTGen.s_dicTreeInfoList)
            {
                int cnkidx = RSubTerrUtils.TilePosToIndex(kvp.Key);
                _lstChnkIdxActive.Add(cnkidx);
                if (m_Chunks.ContainsKey(cnkidx))
                {
                    continue;
                }
                int        cnkx    = RSubTerrUtils.IndexToChunkX(cnkidx);
                int        cnkz    = RSubTerrUtils.IndexToChunkZ(cnkidx);
                GameObject chunkgo = new GameObject("Tile [" + cnkx + "," + cnkz + "]");
                chunkgo.transform.parent   = s_Instance.ChunkGroup.transform;
                chunkgo.transform.position = new Vector3((cnkx + 0.5f) * RSubTerrConstant.ChunkSizeF, 0, (cnkz + 0.5f) * RSubTerrConstant.ChunkSizeF);
                RSubTerrainChunk chunk = chunkgo.AddComponent <RSubTerrainChunk>();
                chunk.m_Index = cnkidx;
                s_Instance.m_Chunks.Add(cnkidx, chunk);
                foreach (TreeInfo ti in kvp.Value)
                {
                    bool was_deleted = false;
                    // Delete cutted trees
                    if (RSubTerrSL.m_mapDelPos != null)
                    {
                        for (int x = cnkx - 1; x <= cnkx + 1; ++x)
                        {
                            for (int z = cnkz - 1; z <= cnkz + 1; ++z)
                            {
                                int idx = RSubTerrUtils.ChunkPosToIndex(x, z);
                                if (RSubTerrSL.m_mapDelPos.ContainsKey(idx))
                                {
                                    foreach (Vector3 pos in RSubTerrSL.m_mapDelPos[idx])
                                    {
                                        float diff = Mathf.Abs(pos.x - ti.m_pos.x) + Mathf.Abs(pos.y - ti.m_pos.y) + Mathf.Abs(pos.z - ti.m_pos.z);
                                        if (diff < 0.05f)
                                        {
                                            was_deleted = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (was_deleted)
                    {
                        continue;
                    }

                    chunk.AddTree(ti);
                    int idx32 = RSubTerrUtils.Tree32PosTo32Index(Mathf.FloorToInt(ti.m_pos.x / 32), Mathf.FloorToInt(ti.m_pos.z / 32));
                    if (!m_map32Trees.ContainsKey(idx32))
                    {
                        m_map32Trees.Add(idx32, new List <TreeInfo>());
                    }
                    if (HasCollider(ti.m_protoTypeIdx) || HasLight(ti.m_protoTypeIdx))
                    {
                        m_map32Trees[idx32].Add(ti);
                    }
                }
                if (IsChunkRendering(cnkidx))
                {
                    m_IsDirty = true;
                }
            }

            _lstChnkIdxToDel.Clear();
            foreach (KeyValuePair <int, RSubTerrainChunk> kvp in m_Chunks)
            {
                if (!_lstChnkIdxActive.Contains(kvp.Key))
                {
                    _lstChnkIdxToDel.Add(kvp.Key);
                }
            }
            foreach (int key in _lstChnkIdxToDel)
            {
                RemoveChunk(key);
                if (IsChunkRendering(key))
                {
                    m_IsDirty = true;
                }
            }
            Monitor.Exit(VFDataRTGen.s_dicTreeInfoList);
        }
    }