public void Generate() { ManualResetEvent[] genWait = new ManualResetEvent[threadsNum]; ThreadPool.SetMaxThreads(threadsNum, threadsNum); int totalLoops = (Math.Abs(fromChunkX) + Math.Abs(toChunkX)); int basePartition = totalLoops / threadsNum; int remainder = totalLoops - (basePartition * threadsNum); int currStartX, currEndX, oldEndX; currStartX = currEndX = oldEndX = fromChunkX; int extraWork; GenPool = new ChunkGeneratorPool(threadsNum, worldSeed); for (int i = 0; i < threadsNum; ++i) { extraWork = remainder > 0 ? 1 : 0; --remainder; currStartX = oldEndX; currEndX += basePartition + extraWork; oldEndX = currEndX; genWait[i] = new ManualResetEvent(false); ChunkGenThreadEntry chunkGenEntry = new ChunkGenThreadEntry(currStartX, currEndX, GenPool, (chunkGen, x) => { int xComponent = (x + Math.Abs(fromChunkX)) * (toChunkX - fromChunkX); for (int z = fromChunkX; z < toChunkX; ++z) { ushort index = WorldBehaviour.ChunkIndexFromCoords(x, z); Chunk chunk = new Chunk(x, z, worldManager, (z + x) % 2 == 0 ? Color.black : Color.gray); chunkGen.GenerateChunk(chunk, x, z); int entryIndex = xComponent + (z + Math.Abs(fromChunkX)); chunkEntries[entryIndex] = new ChunkMeshThreadEntry(chunk); WorldBehaviour.ChunksMap[index] = chunk; } }); ThreadPool.QueueUserWorkItem(new WaitCallback(chunkGenEntry.ThreadCallback), genWait[i]); } WaitHandle.WaitAll(genWait); }
void Start() { Menu.Instance.showPanel("LoadingPanel"); BlockMaterial = (Material)Resources.Load("Materials/BlockVertex", typeof(Material)); AtlasTexture = (Texture2D)Resources.Load("Textures/Terrain"); if (AtlasTexture == null) { Debug.Log("Terrain texture not loaded"); } ChunkMeshThreadEntry[] chunkEntries = new ChunkMeshThreadEntry[ChunksNum]; ChunkGenManager chunkGenManager = new ChunkGenManager(MapMinChunkX, MapMaxChunkX + 1, 6, this, 13284938921, chunkEntries); chunkGenManager.Generate(); for (int x = 0; x < ChunksNum; ++x) { chunkEntries[x].Init(); ThreadPool.QueueUserWorkItem(new WaitCallback(chunkEntries[x].ThreadCallback)); } }