public void ClearCache() { CompleteCellLoading(); for (int i = 0; i <= LoadedVegetationCellList.Count - 1; i++) { LoadedVegetationCellList[i].ClearCache(); } LoadedVegetationCellList.Clear(); ClearBillboardCellsCache(); OnClearCacheDelegate?.Invoke(this); }
public void ClearCache(Bounds bounds) { Rect clearRect = RectExtension.CreateRectFromBounds(bounds); CompleteCellLoading(); //TODO Use quadtree here for (int i = LoadedVegetationCellList.Count - 1; i >= 0; i--) { VegetationCell vegetationCell = LoadedVegetationCellList[i]; if (!vegetationCell.Rectangle.Overlaps(clearRect)) { continue; } vegetationCell.ClearCache(); LoadedVegetationCellList.RemoveAtSwapBack(i); OnClearCacheVegetationCellDelegate?.Invoke(this, vegetationCell); } ClearBillboardCellsCache(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(); }
private void CreateVegetationCells() { DisposeVegetationCells(); Bounds expandedBounds = new Bounds(VegetationSystemBounds.center, VegetationSystemBounds.size); expandedBounds.Expand(new Vector3(VegetationCellSize * 2f, 0, VegetationCellSize * 2f)); Rect expandedRect = RectExtension.CreateRectFromBounds(expandedBounds); VegetationCellQuadTree = new QuadTree <VegetationCell>(expandedRect); int cellXCount = Mathf.CeilToInt(VegetationSystemBounds.size.x / VegetationCellSize); int cellZCount = Mathf.CeilToInt(VegetationSystemBounds.size.z / VegetationCellSize); Vector2 corner = new Vector2(VegetationSystemBounds.center.x - VegetationSystemBounds.size.x / 2f, VegetationSystemBounds.center.z - VegetationSystemBounds.size.z / 2f); for (int x = 0; x <= cellXCount - 1; x++) { for (int z = 0; z <= cellZCount - 1; z++) { VegetationCell vegetationCell = new VegetationCell(new Rect( new Vector2(VegetationCellSize * x + corner.x, VegetationCellSize * z + corner.y), new Vector2(VegetationCellSize, VegetationCellSize))); VegetationCellList.Add(vegetationCell); vegetationCell.Index = VegetationCellList.Count - 1; VegetationCellQuadTree.Insert(vegetationCell); } } LoadedVegetationCellList.Clear(); LoadedVegetationCellList.Capacity = VegetationCellList.Count; NativeArray <Bounds> vegetationCellBounds = new NativeArray <Bounds>(VegetationCellList.Count, Allocator.Persistent); for (int i = 0; i <= VegetationCellList.Count - 1; i++) { vegetationCellBounds[i] = VegetationCellList[i].VegetationCellBounds; } 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, expandedRect, jobHandle); } jobHandle.Complete(); for (int i = 0; i <= VegetationCellList.Count - 1; i++) { VegetationCellList[i].VegetationCellBounds = vegetationCellBounds[i]; } vegetationCellBounds.Dispose(); PrepareVegetationCells(); VegetationStudioManager.OnVegetationCellRefresh(this); }