void Apply(bool createAssets) { heightsFile = EditorUtility.OpenFilePanel("Select heights definitions file", Application.dataPath, ""); PathReader path = new PathReader(heightsFile); float pathLength = path.GetMaxValue(); chunksCount = ((int)(pathLength + 1)) / chunkSize; if (createAssets) { GenerateTerrains(chunksCount); } /************ * GET TERRAINS ********/ sceneTerrains = FindObjectsOfType(typeof(Terrain)) as Terrain[]; if (sceneTerrains.Length == 0 || chunksCount != sceneTerrains.Length) { EditorUtility.DisplayDialog("Error", "The number of terrains does not match input file", "Ok"); return; } //ORDER BY Z System.Array.Sort(sceneTerrains, zComparator); /**************************** * Your track is between 25% and 75% of the terrain height * *************************/ int maxHeight = path.GetMaxHeight(); int terrainsHeight = maxHeight * 2; float groundOffset = 1f / 4f; //SET TERRAINS NEW HEIGHT for (int i = 0; i < sceneTerrains.Length; i++) { sceneTerrains[i].terrainData.size = new Vector3(chunkSize, terrainsHeight, chunkSize); } /**************** * Use an extend heightmap for the coherent noise (not chunked) * **************/ int extendedHeightmapLength = chunkSize /*heightmapResolution*/ * chunksCount; //NEEDS FIX float[,] extendedHeightmap = new float[heightmapResolution, extendedHeightmapLength]; float value = 0f; int projectionStart = 0; int projectionEnd = 0; /***************** * If the height definition does not start from 0, * the terrain is set to the height of the first point * **************/ int firstPosition = RealPositionToHeightmap(path.points [0].positionProjection); for (int z = 0; z < firstPosition; z++) { for (int x = 0; x < heightmapResolution; x++) { extendedHeightmap[x, z] = path.points [0].height / terrainsHeight + groundOffset; } } /****************************** * Set the slopes according to the heights definition * ***************************/ for (int p = 0; p < path.points.Count - 1; p++) { PathReader.Point s = path.points[p]; PathReader.Point e = path.points[p + 1]; projectionStart = RealPositionToHeightmap(s.positionProjection); projectionEnd = RealPositionToHeightmap(e.positionProjection); float segmentLength = projectionEnd - projectionStart; for (int z = projectionStart; z < projectionEnd; z++) { value = Mathf.Lerp(s.height, e.height, (float)(z - projectionStart) / segmentLength); for (int x = 0; x < heightmapResolution; x++) { extendedHeightmap[x, z] = value / terrainsHeight + groundOffset; } } } /**************************** * The segment from the last point and the end of the terrain * is set to the last height * *************************/ for (int z = projectionEnd; z < extendedHeightmapLength; z++) { for (int x = 0; x < heightmapResolution; x++) { extendedHeightmap[x, z] = value / terrainsHeight + groundOffset; } } //APPLY NOISE float[,] noiseMap = generatePerlin(seed, heightmapResolution, extendedHeightmapLength); //APPLY THE COMPUTED HEIGHTMAP TO THE TERRAINS for (int i = 0; i < sceneTerrains.Length; i++) { float[,] slopes = getTerrainHeightmap(extendedHeightmap, i); float[,] noise = getTerrainHeightmap(noiseMap, i); float[,] mergedHeightMap = new float[heightmapResolution, heightmapResolution]; for (int w = 0; w < heightmapResolution; w++) { int leftPathBorder = (heightmapResolution / 2) - pathWidth; int rightPathBorder = (heightmapResolution / 2) + pathWidth; for (int h = 0; h < leftPathBorder; h++) { float ratio = leftHeight * Mathf.SmoothStep(1, /*1-leftHeight*/ 0, (float)h / (float)leftPathBorder); float noiseValue = (noise[w, h]) * noiseAmount; mergedHeightMap[w, h] = slopes[w, h] + ratio * noiseValue; /*float ratio = Mathf.SmoothStep(0.7f,0,(float)h/(float)leftPathBorder); * float noiseValue = noise[w,h]; * float cliff = Mathf.SmoothStep(0.25f, slopes[w,h],(float)h/(float)leftPathBorder); * mergedHeightMap[w,h] = cliff-ratio*noiseValue;*/ } for (int h = rightPathBorder; h < heightmapResolution; h++) { float ratio = rightHeight * Mathf.SmoothStep(0, /*rightHeight*/ 1, (float)(h - pathWidth - leftPathBorder) / (float)(leftPathBorder)); float noiseValue = (noise[w, h]) * noiseAmount; mergedHeightMap[w, h] = slopes[w, h] + ratio * noiseValue; } for (int h = leftPathBorder; h < rightPathBorder; h++) { mergedHeightMap[w, h] = slopes[w, h]; } } sceneTerrains[i].terrainData.SetHeights(0, 0, mergedHeightMap); } if (createAssets) { CreateLight(); } }