void GenThread() { if (!_isRandomInited) { _isRandomInited = true; _random = new System.Random(_seed); } while (_chunkGenQueue.Count > 0) { if (!_chunkGenQueue.TryDequeue(out var chunkPos)) { break; } var x = chunkPos.X; var z = chunkPos.Z; const int blockCount = (Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SIZE_Z) * (Chunk.CHUNK_SIZE_Y); var blocks = new BlockData[blockCount]; for (int i = 0; i < blockCount; i++) { Execute(i, blocks); } var readyChunk = new GeneratedChunkData(new Int3(x * Chunk.CHUNK_SIZE_X, 0, z * Chunk.CHUNK_SIZE_Z), blocks, _heightmap, GROUND_HEIGHT + 1, 0); _readyChunks.Enqueue(readyChunk); Thread.Sleep(1); } _routineRunning = false; }
IEnumerator ParallelGenRoutine() { if (!_isRandomInited) { _isRandomInited = true; Random.InitState(_seed); _random.InitState((uint)_seed); } while (_chunkGenQueue.Count > 0) { Profiler.BeginSample("Chunk procgen"); if (!_chunkGenQueue.TryDequeue(out var chunkPos)) { break; } var x = chunkPos.X; var z = chunkPos.Z; var heightmapJob = new HeightGenJob() { BaseScale = 20, Seed = _seed, SizeX = Chunk.CHUNK_SIZE_X, SizeY = Chunk.CHUNK_SIZE_Z, OffsetX = Chunk.CHUNK_SIZE_X * x, OffsetY = Chunk.CHUNK_SIZE_Z * z, Height = new Unity.Collections.NativeArray <byte>(Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SIZE_Z, Unity.Collections.Allocator.Persistent) }; var hHandle = heightmapJob.Schedule(256, 128); hHandle.Complete(); var waterLevel = Utils.WorldOptions.WaterLevel; var blockCount = Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SIZE_Y * Chunk.CHUNK_SIZE_Z; var fillJob = new ChunkGenJob() { SizeH = Chunk.CHUNK_SIZE_X, SizeY = Chunk.CHUNK_SIZE_Y, Random = _random, SeaLevel = waterLevel, HeightMap = heightmapJob.Height, Blocks = new Unity.Collections.NativeArray <BlockData>(blockCount, Unity.Collections.Allocator.Persistent) }; var fillHandler = fillJob.Schedule(blockCount, 512); var height = heightmapJob.Height.ToArray(); var maxY = waterLevel; for (int i = 0; i < height.Length; i++) { if (height[i] > maxY) { maxY = height[i]; } } Profiler.EndSample(); if (!ImmediateMode) { yield return(new WaitForEndOfFrame()); } fillHandler.Complete(); var readyChunk = new GeneratedChunkData(new Int3(x * Chunk.CHUNK_SIZE_X, 0, z * Chunk.CHUNK_SIZE_Z), fillJob.Blocks.ToArray(), heightmapJob.Height.ToArray(), maxY + 1, waterLevel); _readyChunks.Enqueue(readyChunk); heightmapJob.Height.Dispose(); fillJob.Blocks.Dispose(); } _routineRuuning = false; yield break; }