// NOTE: we must renounce chunk computing in the display thread // to ensure that we don't scuttle the buffers with overlapping compute calls public async Task <ColumnAndHeightMap <ChunkGenData> > ComputeColumnAtAsync(Column <ChunkGenData> column, Func <IntVector3, ChunkGenData> GetFromMemory) { //...Set data for the heightmap ColumnAndHeightMap <ChunkGenData> cah = new ColumnAndHeightMap <ChunkGenData>(); cah.column = column; cah.heightMap = new HeightMap(vGenConfig.ColumnFootprint); var keys = cah.column.Keys.ToArray(); int dbugComputedCount = 0; for (int i = 0; i < keys.Length; ++i) { var data = GetFromMemory(cah.column.position.ToIntVector3XZWithY(keys[i])); if (data == null) { dbugComputedCount++; data = (ChunkGenData)(await ComputeGenData(cah.column.position.ToIntVector3XZWithY(keys[i]))); } cah.column[keys[i]] = data; } //TODO: set height map data //int[] heights = CVoxelMapFormat.BufferCountArgs.GetData<int>(cvoxelMapData.MapHeights); //TODO: fill with actual data //FAKENESS int[] heights = FakeChunkData.FakeHeights(vGenConfig.ChunkSize, keys.OrderByDescending((k) => k).ToArray()[0]); cah.heightMap.setData(heights); return(cah); }
internal async Task Process(ColumnAndHeightMap <NeighborChunkGenData> colAndHeightMap, Action <IntVector3> OnWroteChunkData) { var keys = colAndHeightMap.column.Keys.OrderByDescending(a => a); foreach (var key in keys) { await ProcessSet(colAndHeightMap.column[key], OnWroteChunkData); } }
public async Task PostProcessColumnAsync(ColumnAndHeightMap <NeighborChunkGenData> columnAndHeightMap, Action <IntVector3> OnWroteChunkData) { // // Work from top to bottom. (TODO: propagate bootstrap data downwards) // var keys = columnAndHeightMap.column.Keys.OrderByDescending(a => a); foreach (var key in keys) { await PostProcessSetAsync(columnAndHeightMap.column[key], OnWroteChunkData); } }
async Task _ProcessColumn(ColumnAndHeightMap <NeighborChunkGenData> colAndHeightMap) { // compute runs a compute shader (a version of mesh-gen) that also gets await compute.PostProcessColumnAsync(colAndHeightMap, (IntVector3 chunkPos) => { CompletedChunkAt(chunkPos); }); //a (massive?) ExistsMap27 /* * await processColumn.Process(colAndHeightMap, (IntVector3 chunkPos) => * { * CompletedChunkAt(chunkPos); * }); */ }
// TODO: have the genArea update when this // whole process is done // what do we want? // a collection of available chunk coords // TODO: add a mechanism to know whether we need to re compute all of these chunks at all // however also have a debug-compute-anyway flag async Task <ColumnMap3 <NeighborChunkGenData> > GenerateAsync() { // for the genArea // possibly: // bootstrap some seed data. // such as a known full light voxel // maybe? this function runs once per job: e.g. per light distribution, structure distribution //// // bootstrap data comes from somewhere // foreach chunk containing some bootstrap data: // Add the data for that chunk var area = genArea; purgeLookup(); processSet.Clear(); notYetProcessed.Clear(); chunkGenTasks.Clear(); columnLookup.Clear(); var positions = GenAreaPositions; foreach (var centerChunkPos in positions) { notYetProcessed.Add(centerChunkPos); } // // TODO: use metadata. has been processed. <<--- yeah // Don't need to re-compute processed chunks. // // Per column: // bounds. IteratorXZ etc.. // then get the XZ neighbors also... the ones not contained in bounds.xz // Get a Column and HeightMap from compute chunks<ChunkGenData> // with each of these add the CGD to lookup //TODO: for structures we need all 27 //and kind of want Octrees var outerShellArea = area.bounds.ExpandedBordersAdditive(IntVector3.one); foreach (var centerChunkPos in IterBounds.IteratorXZAtY(outerShellArea, outerShellArea.end.y)) { // NOTE: possibly we already computed this column as a neighbor outside bounds // need a mechanism (player prefs?) for checking if we've already written these columns/chunks somewhere var col = new Column <ChunkGenData>(centerChunkPos.xz); col.SetRangeToDefault(outerShellArea.start.y, outerShellArea.end.y); //TRY: // ComputeColumnAtAsync only does the perlin gen var colheight = await compute.ComputeColumnAtAsync(col, (IntVector3 pos) => { if (lookup.ContainsKey(pos)) { return(lookup[pos]); } return(null); }); columnLookup.AddOrSet(col.position, colheight); } foreach (var centerChunkPos in positions) { processSet.SetItem(centerChunkPos, new NeighborChunkGenData(centerChunkPos)); } foreach (var centerChunkPos in outerShellArea.IteratorXYZ) { var gendata = columnLookup[centerChunkPos.xz].column[centerChunkPos.y]; lookup.AddOrSet(centerChunkPos, gendata); } foreach (var col in processSet.GetColumns()) { foreach (var nei in col.Values) { nei.GatherData27((IntVector3 pos) => { try { return(lookup[pos]); } catch (IndexOutOfRangeException ior) { throw ior; } }); } var colAndHeight = new ColumnAndHeightMap <NeighborChunkGenData> { column = col, heightMap = columnLookup[col.position].heightMap }; await _ProcessColumn(colAndHeight); } return(processSet); }