public void RefreshTerrainArea(Bounds bounds)
        {
            if (VegetationCellQuadTree == null)
            {
                return;
            }

            List <VegetationCell> overlapVegetationCellList = new List <VegetationCell>();
            Rect updateRect = RectExtension.CreateRectFromBounds(bounds);

            VegetationCellQuadTree.Query(updateRect, overlapVegetationCellList);

            Bounds updateBounds = bounds;

            NativeArray <Bounds> vegetationCellBounds =
                new NativeArray <Bounds>(overlapVegetationCellList.Count, Allocator.Persistent);

            for (int i = 0; i <= overlapVegetationCellList.Count - 1; i++)
            {
                Bounds cellBounds = RectExtension.CreateBoundsFromRect(overlapVegetationCellList[i].Rectangle, -100000);
                vegetationCellBounds[i] = cellBounds;
                updateBounds.Encapsulate(cellBounds);
            }

            updateRect = RectExtension.CreateRectFromBounds(updateBounds);

            float minBoundsHeight    = VegetationSystemBounds.center.y - VegetationSystemBounds.extents.y;
            float worldspaceSealevel = minBoundsHeight + SeaLevel;

            if (!ExcludeSeaLevelCells)
            {
                worldspaceSealevel = minBoundsHeight;
            }

            JobHandle jobHandle = default(JobHandle);

            for (int i = 0; i <= VegetationStudioTerrainList.Count - 1; i++)
            {
                jobHandle = VegetationStudioTerrainList[i]
                            .SampleCellHeight(vegetationCellBounds, worldspaceSealevel, updateRect, jobHandle);
            }

            jobHandle.Complete();

            for (int i = 0; i <= overlapVegetationCellList.Count - 1; i++)
            {
                overlapVegetationCellList[i].VegetationCellBounds = vegetationCellBounds[i];
            }

            vegetationCellBounds.Dispose();

            ForceCullingRefresh();
            ClearCache(bounds);
        }
        private void LoadBillboardCells()
        {
            _loadBillboardCellList.Clear();
            Profiler.BeginSample("Load billboard cells");
            _billboardTempVegetationCellList.Clear();
            VegetationCellSpawner.CellJobHandleList.Clear();

            Profiler.BeginSample("Find billboard cells with quadtree");
            for (var i = 0; i <= VegetationStudioCameraList.Count - 1; i++)
            {
                if (!VegetationStudioCameraList[i].Enabled)
                {
                    continue;
                }

                for (var j = 0;
                     j <= VegetationStudioCameraList[i].BillboardJobCullingGroup.VisibleCellIndexList.Length - 1;
                     j++)
                {
                    var index         = VegetationStudioCameraList[i].BillboardJobCullingGroup.VisibleCellIndexList[j];
                    var billboardCell = BillboardCellList[index];
                    if (billboardCell.Loaded)
                    {
                        continue;
                    }

                    billboardCell.OverlapVegetationCells.Clear();
                    VegetationCellQuadTree.Query(billboardCell.Rectangle, billboardCell.OverlapVegetationCells);

                    _billboardTempVegetationCellList.AddRange(billboardCell.OverlapVegetationCells);

                    if (!_loadBillboardCellList.Contains(billboardCell))
                    {
                        _loadBillboardCellList.Add(billboardCell);
                    }
                }
            }

            Profiler.EndSample();

            Profiler.BeginSample("Load needed cells");
            for (var i = 0; i <= _billboardTempVegetationCellList.Count - 1; i++)
            {
                var vegetationCell = _billboardTempVegetationCellList[i];
                if (vegetationCell.LoadedDistanceBand <= 1)
                {
                    continue;
                }
                if (vegetationCell.LoadedBillboards)
                {
                    continue;
                }

                if (!Application.isPlaying && !vegetationCell.Prepared)
                {
                    VegetationCellSpawner.PrepareVegetationCell(vegetationCell);
                }

                // ReSharper disable once InlineOutVariableDeclaration
                bool hasInstancedIndirect;

                var spawnVegetationCellHandle = VegetationCellSpawner.SpawnVegetationCell(vegetationCell, 1, out hasInstancedIndirect, true);
                CompactMemoryCellList.Add(vegetationCell);
                LoadedVegetationCellList.Add(vegetationCell);
#if UNITY_EDITOR
                if (JobsUtility.JobDebuggerEnabled)
                {
                    spawnVegetationCellHandle.Complete();
                    ReturnVegetationCellTemporaryMemory();
                }
#endif
                VegetationCellSpawner.CellJobHandleList.Add(spawnVegetationCellHandle);
                if (hasInstancedIndirect)
                {
                    ProcessInstancedIndirectCellList.Add(vegetationCell);
                }
            }

            var loadAllCellsHandle = JobHandle.CombineDependencies(VegetationCellSpawner.CellJobHandleList);
            VegetationCellSpawner.CellJobHandleList.Clear();

            Profiler.EndSample();

            Profiler.BeginSample("Merge cells and create mesh data");

            for (var i = 0; i <= _loadBillboardCellList.Count - 1; i++)
            {
                var billboardCell = _loadBillboardCellList[i];
                if (billboardCell.Loaded)
                {
                    continue;
                }

                for (var j = 0; j <= billboardCell.VegetationPackageBillboardInstancesList.Count - 1; j++)
                {
                    for (var k = 0;
                         k <= billboardCell.VegetationPackageBillboardInstancesList[j].BillboardInstanceList.Count - 1;
                         k++)
                    {
                        var vegetationItemInfoPro = VegetationPackageProList[j].VegetationInfoList[k];
                        if (vegetationItemInfoPro.VegetationType != VegetationType.Tree)
                        {
                            continue;
                        }

                        var billboardInstance = billboardCell.VegetationPackageBillboardInstancesList[j]
                                                .BillboardInstanceList[k];
                        if (billboardInstance.Loaded)
                        {
                            continue;
                        }

                        var billboardPrepareMeshDataJobHandle = loadAllCellsHandle;
                        for (var l = 0; l <= billboardCell.OverlapVegetationCells.Count - 1; l++)
                        {
                            var vegetationCell   = billboardCell.OverlapVegetationCells[l];
                            var cellInstanceList =
                                vegetationCell.VegetationPackageInstancesList[j].VegetationItemMatrixList[k];

                            var mergeCellInstancesJob = new MergeCellInstancesJob
                            {
                                OutputNativeList = billboardInstance.InstanceList, InputNativeList = cellInstanceList
                            };

                            billboardPrepareMeshDataJobHandle =
                                mergeCellInstancesJob.Schedule(billboardPrepareMeshDataJobHandle);
                        }

                        var vegetationItemSize = Mathf.Max(vegetationItemInfoPro.Bounds.extents.x,
                                                           vegetationItemInfoPro.Bounds.extents.y,
                                                           vegetationItemInfoPro.Bounds.extents.z) * 2f;

                        var createBillboardMeshJob = new BillboardGenerator.CreateBillboardMeshJob
                        {
                            InstanceList       = billboardInstance.InstanceList,
                            VerticeList        = billboardInstance.VerticeList,
                            NormalList         = billboardInstance.NormalList,
                            UvList             = billboardInstance.UvList,
                            Uv2List            = billboardInstance.Uv2List,
                            Uv3List            = billboardInstance.Uv3List,
                            IndexList          = billboardInstance.IndexList,
                            BoundsYExtent      = vegetationItemInfoPro.Bounds.extents.y,
                            VegetationItemSize = vegetationItemSize
                        };

                        billboardPrepareMeshDataJobHandle =
                            createBillboardMeshJob.Schedule(billboardPrepareMeshDataJobHandle);
                        VegetationCellSpawner.CellJobHandleList.Add(billboardPrepareMeshDataJobHandle);
                    }
                }
            }

            var combinedMergeJobHandle = JobHandle.CombineDependencies(VegetationCellSpawner.CellJobHandleList);
            VegetationCellSpawner.CellJobHandleList.Clear();
            loadAllCellsHandle.Complete();
            combinedMergeJobHandle.Complete();
            Profiler.EndSample();

            Profiler.BeginSample("Create Mesh Objects");
            for (var i = 0; i <= _loadBillboardCellList.Count - 1; i++)
            {
                var billboardCell = _loadBillboardCellList[i];
                if (billboardCell.Loaded)
                {
                    continue;
                }
                for (var j = 0; j <= billboardCell.VegetationPackageBillboardInstancesList.Count - 1; j++)
                {
                    for (var k = 0;
                         k <= billboardCell.VegetationPackageBillboardInstancesList[j].BillboardInstanceList.Count - 1;
                         k++)
                    {
                        var billboardInstance = billboardCell.VegetationPackageBillboardInstancesList[j]
                                                .BillboardInstanceList[k];
                        if (billboardInstance.Loaded)
                        {
                            continue;
                        }
                        billboardInstance.InstanceCount = billboardInstance.InstanceList.Length;
                        if (billboardInstance.InstanceCount > 0)
                        {
                            billboardInstance.Mesh = BillboardGenerator.CreateMeshFromBillboardInstance(billboardInstance);
                        }
                        billboardInstance.Loaded = true;
                    }
                }

                billboardCell.Loaded = true;
            }

            _loadBillboardCellList.Clear();
            Profiler.EndSample();

            Profiler.EndSample();
        }