/// <summary> /// Generate Midpoint Displacement procedurally /// /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="crackedPercent"></param> /// <param name="iterationsPercent"></param> /// <param name="crackDirectionChangePercent"></param> /// <param name="crackLengthPercent"></param> /// <returns>Bitmap stream in jpg format</returns> public async Task <Stream> GetMidpointDisplacement(int width, int height, int crackedPercent, int iterationsPercent, int crackDirectionChangePercent, int crackLengthPercent) { if ((crackedPercent < 1) || (crackedPercent > 100)) { throw new ArgumentException(nameof(crackedPercent) + " must between 1 and 100"); } if ((iterationsPercent < 1) || (iterationsPercent > 100)) { throw new ArgumentException(nameof(iterationsPercent) + " must between 1 and 100"); } if ((crackDirectionChangePercent < 1) || (crackDirectionChangePercent > 100)) { throw new ArgumentException(nameof(crackDirectionChangePercent) + " must between 1 and 100"); } if ((crackLengthPercent < 1) || (crackLengthPercent > 100)) { throw new ArgumentException(nameof(crackLengthPercent) + " must between 1 and 100"); } return(await Task.Run(() => { return GetStreamFromBitmap(MidpointDisplacement.Generate(Width: width, Height: height, NumberOfCracks: crackedPercent, Iterations: iterationsPercent, MaxChange: crackDirectionChangePercent / 10, MaxLength: crackLengthPercent, Seed: Guid.NewGuid().GetHashCode())); })); }
void Generate() { CleanUp(); _chunks = new Chunk[Mathf.FloorToInt(size / chunkSize), Mathf.FloorToInt(worldHeight / chunkSize), Mathf.FloorToInt(size / chunkSize)]; //первый запуск, строим землю if (!_needToLoad) { _mpd = new MidpointDisplacement(size, roughFactor, 0, worldHeight, worldHeight*0.8f); _mpd.SetBaseValue(); _mpd.SetRandomValue(); _mpd.Generate(roughValues); _worldData = new float[size, worldHeight, size]; //generate all world data for (int i = 0; i < size*size; i++) { float height = Mathf.Min(_mpd.data[(int) i/size, i%size], worldHeight - 1); for (int h = 0; h < (int) (height); h++) _worldData[(int) i/size, h, i%size] = 1; if (smooth) { if (height >= 0) _worldData[(int) i/size, (int) (height), i%size] = height - (int) height; } } //разбивает worldData на чанки for (var i = 0; i < _chunks.GetLength(0); i++) { for (var j = 0; j < _chunks.GetLength(1); j++) { for (var k = 0; k < _chunks.GetLength(2); k++) { float chunkX = (i * chunkSize); float chunkY = (j * chunkSize); float chunkZ = (k * chunkSize); _chunks[i, j, k] = CreateChunk(chunkX, chunkY, chunkZ); Block[, ,] chunkData = WorldToBlocks((int)chunkX, (int)chunkY, (int)chunkZ); _chunks[i, j, k].Initialize(chunkData, chunkSize, chunkMaterial, this); } } } } else { var terrain = GameSaver.Instance.LoadTerrain(); var chunksSaveData = Helper.SingleToMulti(terrain.Chunk_0, terrain.Chunk_1, terrain.Chunk_2, terrain.Chunks); for (var i = 0; i < _chunks.GetLength(0); i++) { for (var j = 0; j < _chunks.GetLength(1); j++) { for (var k = 0; k < _chunks.GetLength(2); k++) { var saveData = chunksSaveData[i, j, k]; _chunks[i, j, k] = CreateChunk(saveData.Position.x, saveData.Position.y, saveData.Position.z); _chunks[i, j, k].Initialize(saveData, chunkSize, chunkMaterial, this); } } } terrain = null; chunksSaveData = null; _needToLoad = false; } RegenerateAllChunks(); }
public void Zero_sub_divisions_returns_original_corners() { var result = _sut.Generate(0, 2, 4, 8, 0, 0); result.Should().BeEquivalentTo(0.0, 2.0, 4.0, 8.0); }