public float CalculateNoiseValue(NoiseAlgorithm noiseAlgorithm, float i, float j, Terrain chunk, float[] args) { float noiseValue = 0.0f; switch (noiseData.type) { case eNoise.FRACTAL: { noiseValue = (float)(noiseAlgorithm.RidgedMultiFractal((seed.x + (float)i / (float)chunk.terrainData.heightmapHeight), (seed.y + (float)j / (float)chunk.terrainData.heightmapWidth), (int)args[0], args[1], args[2], args[3])) / noiseData.size; break; } case eNoise.FBM: { noiseValue = (float)(noiseAlgorithm.FractionalBrownianMotion((seed.x + (float)i / (float)chunk.terrainData.heightmapHeight), (seed.y + (float)j / (float)chunk.terrainData.heightmapWidth), (int)args[0], args[1], args[2], args[3])) / noiseData.size; break; } case eNoise.BILLOW: { noiseValue = (float)(noiseAlgorithm.Billow((seed.x + (float)i / (float)chunk.terrainData.heightmapHeight), (seed.y + (float)j / (float)chunk.terrainData.heightmapWidth), (int)args[0], args[1], args[2], args[3])) / noiseData.size; break; } } return(noiseValue); }
// ################################################################################################################### // ################################################################################################################### // ################################################################################################################### public override void GenerateNoise(bool update) { // #### Adds base noise in whole terrain #### //generate(dir, type, update); NoiseAlgorithm noiseAlgorithm = new NoiseAlgorithm(); int totalHeight = (_chunks[0, 0].chunkTerrain.terrainData.heightmapHeight - 1) * chunksY; int totalWidth = (_chunks[0, 0].chunkTerrain.terrainData.heightmapWidth - 1) * chunksX; int x = 0, y = 0; int ix = 1, iy = 1; // Starting for first chunk grid ("00") // 01 11 // 00 10 Terrain chunk = _chunks[x, y].chunkTerrain; Terrain chunk_init = chunk; float[,] heights = chunk.terrainData.GetHeights(0, 0, chunk.terrainData.heightmapHeight, chunk.terrainData.heightmapWidth); float[,] heights_init = heights; int initH = (int)chunk.transform.position.z; int initW = (int)chunk.transform.position.x; int endH = initH + totalHeight; int endW = initW + totalWidth; int currentHeight = initH + (chunk.terrainData.heightmapHeight - 2); int currentWidth = initW + (chunk.terrainData.heightmapWidth - 1); Vector2 center = new Vector2(totalWidth * 0.5f, totalHeight * 0.5f); float offset = (chunksX == chunksY ? 0.85f : 1f); float MaxDistance2Center = Vector2.Distance(center, new Vector2(0, 0)) * offset; // List for store/apply heights optimally List <float[, ]> nextHeights = StoreNextHeights(y); NoiseLayer noiseLayer = NoiseManager.noiseLayers[NoiseManager.currLayer]; // Set seed depending of seedIgnore noiseLayer.seed.x = (noiseLayer.seedIgnore ? (Random.value * 10f) : noiseLayer.seed.x); noiseLayer.seed.y = (noiseLayer.seedIgnore ? (Random.value * 10f) : noiseLayer.seed.y); // GetData en auxiliar variable, for don't erase noiseLayer data float[] args = noiseLayer.GetData(); int acum = update ? 0 : 1; UnityEditor.Undo.RegisterCompleteObjectUndo(chunk.terrainData, "Noise"); // Loop total height for (int i = initH; i <= endH; i++) { //Loop total width for (int j = initW; j < endW; j++) { if (j == currentWidth - 1) { // Store to heights lists nextHeights[x] = heights; ix = 1; x++; if (x < chunksX) { // Get next x-chunk (the chunk "10") , and update limit of currentWidth (cause it have a new position) // 01 11 // 00 10 chunk = _chunks[x, y].chunkTerrain; currentWidth += (chunk.terrainData.heightmapWidth - 1); heights = nextHeights[x]; } } else { float noiseValue = 0.0f; // Do noise depending on type noise. See the function noiseValue = noiseLayer.CalculateNoiseValue(noiseAlgorithm, i, j, chunk, args); float distance2center = Vector2.Distance(center, new Vector2(j, i)); //float flattenGrade = (dir == "+" || dir == "-" ? 1f : 1f - (distance2center / MaxDistance2Center)); float flattenGrade = 1f - (distance2center / MaxDistance2Center); if (!noiseLayer.islandMode) { flattenGrade = 1f; } float heighresult = noiseValue * flattenGrade; // if we have "update" to TRUE then "acum" equals to ZERO,.. // so if (heights * acum = 0), then it doesn't accumulate value over previous heights heights[iy, ix] = (heights[iy, ix] * acum) + heighresult; ix++; } } x = 0; ix = 1; iy++; if (i == currentHeight - 1) { // In our example. Apply first heights in chunks "00" and "10". (In the next chance in chunks "01" and "11"...) ApplyStoreHeights(nextHeights, y); iy = 1; y++; if (y < chunksY) { // Get next y-chunk (the chunk "01") , and update limit of currentHeight (cause it have a new position) // 01 11 // 00 10 chunk = _chunks[x, y].chunkTerrain; currentHeight += (chunk.terrainData.heightmapHeight - 2); chunk_init = chunk; heights_init = chunk.terrainData.GetHeights(0, 0, chunk.terrainData.heightmapHeight, chunk.terrainData.heightmapWidth); nextHeights = StoreNextHeights(y); } else { // end algorithm ... return; } } else { // Back to initial chunk (in our example: back to "01") chunk = chunk_init; } heights = heights_init; currentWidth = (int)chunk.transform.position.x + (chunk.terrainData.heightmapWidth - 1); } }