public void SpawnVegetationCell(VegetationCell vegetationCell, string vegetationItemID) { CompleteCellLoading(); if (!vegetationCell.Prepared) { VegetationCellSpawner.PrepareVegetationCell(vegetationCell); } bool hasInstancedIndirect; JobHandle cellSpawnHandle = VegetationCellSpawner.SpawnVegetationCell(vegetationCell, vegetationItemID, out hasInstancedIndirect); cellSpawnHandle.Complete(); if (!hasInstancedIndirect || !Application.isPlaying) { return; } ProcessInstancedIndirectCellList.Add(vegetationCell); JobHandle prepareInstancedIndirectHandle = PrepareInstancedIndirectSetupJobs(); prepareInstancedIndirectHandle.Complete(); SetupInstancedIndirectComputeBuffers(); ReturnVegetationCellTemporaryMemory(vegetationCell); }
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(); }