// ################################################################################################################### // ################################################################################################################### // ################################################################################################################### 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); } }
private void Draw(ref float value) { if (EditorGUILayout.BeginFadeGroup(value)) { GUI.skin = ResourceLoader.Skin3; EditorGUILayout.IntField("id", NoiseManager.currLayer + 1); GUI.skin = null; GUI.skin = ResourceLoader.Skin2; for (int i = 0; i < NoiseManager.noiseLayers.Count; ++i) { if (GUILayout.Button("NoiseLayer " + (i + 1) + " ■ " + NoiseManager.noiseLayers[i].noiseData.presetName)) { NoiseManager.currLayer = i; } } GUI.skin = null; GUI.skin = ResourceLoader.Skin3; EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("+")) { NoiseManager.noiseLayers.Add(new NoiseLayer()); NoiseManager.Next(); } if (GUILayout.Button("-")) { NoiseManager.noiseLayers.RemoveAt(NoiseManager.currLayer); NoiseManager.Next(); } if (GUILayout.Button("Save")) { NoiseManager.Save(Paths.NoiseLayers + "NoiseLayerDataSaved"); } if (GUILayout.Button("Load")) { NoiseManager.Load(Paths.NoiseLayers + "NoiseLayerDataSaved"); } EditorGUILayout.EndHorizontal(); GUI.skin = null; ResetSkin(); if (NoiseManager.noiseLayers.Count != 0) { EditorGUILayout.Separator(); noiseLayer = NoiseManager.noiseLayers[NoiseManager.currLayer]; if (!dynamicUpdate) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("ApplyLayer")) { addnoise = true; } if (GUILayout.Button("ClearLayer")) { clearnoise = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("ApplyAllLayers")) { addnoise = true; allLayers = true; } if (GUILayout.Button("ClearAllLayers")) { clearnoise = true; allLayers = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); height = EditorGUILayout.Slider("Modify base height ", height, -1f, 1f); if (GUILayout.Button("Apply")) { WorldManagerInspector.worldManager.ChangeBaseHeight(height); WorldManagerInspector.worldManager.noised = true; } EditorGUILayout.EndHorizontal(); } EditorGUILayout.Separator(); EditorGUILayout.Separator(); noiseLayer.seed = EditorGUILayout.Vector2Field("Seed", noiseLayer.seed); noiseLayer.seedIgnore = EditorGUILayout.Toggle("RandSeed", noiseLayer.seedIgnore); noiseLayer.islandMode = EditorGUILayout.Toggle("IslandMode", noiseLayer.islandMode); EditorGUILayout.Separator(); EditorGUILayout.Separator(); show2 = EditorGUILayout.Foldout(show2, "NoiseData"); if (show2) { GUI.skin = null; EditorGUILayout.BeginHorizontal(); string[] noise_str = new string[3]; int[] noise_int = new int[3]; noise_str[0] = eNoise.FRACTAL.ToString(); noise_int[0] = 0; noise_str[1] = eNoise.FBM.ToString(); noise_int[1] = 1; noise_str[2] = eNoise.BILLOW.ToString(); noise_int[2] = 2; noise_selected = EditorGUILayout.IntPopup((int)(noiseLayer.noiseData.type), noise_str, noise_int); dynamicUpdate = GUILayout.Toggle(dynamicUpdate, "DynamicUpdate"); noiseLayer.noiseData.type = (eNoise)(noise_selected); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Octaves"); noiseLayer.noiseData.octaves = EditorGUILayout.IntSlider(noiseLayer.noiseData.octaves, 1, 8); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Persistence"); noiseLayer.noiseData.persistence = EditorGUILayout.Slider(noiseLayer.noiseData.persistence, 0, 2); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Lacunarity"); noiseLayer.noiseData.lacunarity = EditorGUILayout.Slider(noiseLayer.noiseData.lacunarity, 1, 15); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Frequency"); noiseLayer.noiseData.frequency = EditorGUILayout.Slider(noiseLayer.noiseData.frequency, 0, 100); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Size"); noiseLayer.noiseData.size = EditorGUILayout.Slider(noiseLayer.noiseData.size, -50, 50); EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); ResetSkin(); show = EditorGUILayout.Foldout(show, "Save/Load Presets"); if (show) { PresetHandler(); } } if (addnoise || CheckDynamicUpdate()) { if (allLayers) { for (int i = 0; i < NoiseManager.noiseLayers.Count; ++i) { manager.GenerateNoise(dynamicUpdate); NoiseManager.Next(); } allLayers = false; } else { manager.GenerateNoise(dynamicUpdate); } WorldManagerInspector.worldManager.noised = true; addnoise = false; } if (clearnoise) { if (allLayers) { foreach (NoiseLayer layer in NoiseManager.noiseLayers) { layer.noiseData.size = -1f * layer.noiseData.size; manager.GenerateNoise(dynamicUpdate); layer.noiseData.size = -1f * layer.noiseData.size; NoiseManager.Next(); } allLayers = false; } else { noiseLayer.noiseData.size = -1f * noiseLayer.noiseData.size; manager.GenerateNoise(dynamicUpdate); noiseLayer.noiseData.size = -1f * noiseLayer.noiseData.size; } WorldManagerInspector.worldManager.noised = true; clearnoise = false; } SetLastValues(); } GUI.skin = null; EditorGUILayout.Separator(); EditorGUILayout.Separator(); GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) }); EditorGUILayout.Separator(); } EditorGUILayout.EndFadeGroup(); }