private NoiseMapData GenerateNoiseMap(int width, int height, NoiseSettings noiseSettings) { float[,] noiseValues = new float[width, height]; float maxValue = float.MinValue; float minValue = float.MaxValue; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { Vector3 p = new Vector3(); p.x = i / (float)width; p.y = j / (float)height; float noiseValue = Evaluate(p, noiseSettings) / 2 + 0.5f; noiseValues[i, j] = noiseValue; maxValue = Mathf.Max(maxValue, noiseValue); minValue = Mathf.Min(minValue, noiseValue); } } NoiseMapData noiseMapData = new NoiseMapData(); noiseMapData.noiseValues = noiseValues; noiseMapData.minValue = minValue; noiseMapData.maxValue = maxValue; return(noiseMapData); }
public static MeshData GenerateSphereChunkMesh(NoiseMapData noiseMap, SphereMeshSettings sphereSettings, int lod) { int vertexIncrement = sphereSettings.GetVertexIncrement(lod); MarchingCubes mc = new MarchingCubes(sphereSettings.chunkSize / vertexIncrement + 1, sphereSettings.chunkSize / vertexIncrement + 1, sphereSettings.chunkSize / vertexIncrement + 1); mc.init_all(); mc = computeSphereChunk(mc, noiseMap.noiseMap, sphereSettings.noiseHeightScale, sphereSettings.radius, noiseMap.offset, vertexIncrement, sphereSettings.chunkSize); mc.run(); mc.clean_temps(); //TerrainChunk.stopwatch = new System.Diagnostics.Stopwatch(); //TerrainChunk.stopwatch.Start(); MeshData meshData = new MeshData(); meshData.vertices = VertexToVector3Vertices(mc.vertices, mc.nverts(), noiseMap.offset, vertexIncrement); meshData.normals = VertexToVector3Normals(mc.vertices, mc.nverts()); //meshData.uv = NormalsToUVs(mesh.normals); meshData.uv = VerticesToUVs(meshData.vertices); meshData.triangles = TrianglesToInt(mc.triangles, mc.ntrigs()); meshData.lod = lod; //TerrainChunk.stopwatch.Stop(); //Debug.Log("Created MeshData in " + TerrainChunk.stopwatch.ElapsedMilliseconds / 1000f + " seconds"); return(meshData); }
void OnNoiseMapReceived(object noiseMap) { hasNoiseMap = true; //Debug.Log("noiseMap received"); noiseMapData = new NoiseMapData((float[, , ])noiseMap, bounds.min); Update(); }
private void GenerateSurface() { int width = celestialBodySettings.textureSize; int height = celestialBodySettings.textureSize; NoiseMapData noiseMapData = GenerateNoiseMap(width, height, celestialBodySettings.noiseSettings); CelestialBodyColorMap celestialBodyData = GenerateCelestialBodyColorMap(width, height, celestialBodySettings.colorSettings, noiseMapData); Texture2D nightGlowMask = new Texture2D(width, height, TextureFormat.RGBA32, false); nightGlowMask.filterMode = FilterMode.Point; nightGlowMask.SetPixels(celestialBodyData.nightGlowColorMap); nightGlowMask.Apply(); for (int i = 0; i < celestialBodyData.layerColorMaps.GetLength(0); i++) { AddCelestialBodyLayer(width, height, i, celestialBodyData.layerColorMaps[i], nightGlowMask, celestialBodySettings); } }
public static MeshData GenerateSphereMesh(NoiseMapData mapData, SphereMeshSettings sphereSettings, int vertexIncrement) { int mcExpand = Mathf.Min(Mathf.CeilToInt(sphereSettings.noiseHeightScale * sphereSettings.radius * 3) * 2 + 2, 59); int halfMCExpand = mcExpand / 2; Vector3 addOffset = new Vector3(-halfMCExpand, -halfMCExpand, -halfMCExpand); MarchingCubes mc = new MarchingCubes(sphereSettings.chunkSize / vertexIncrement + mcExpand, sphereSettings.chunkSize / vertexIncrement + mcExpand, sphereSettings.chunkSize / vertexIncrement + mcExpand); mc.init_all(); mc = computeSphere(mc, mapData.noiseMap, sphereSettings.noiseHeightScale, sphereSettings.radius, mapData.offset, vertexIncrement, sphereSettings.chunkSize, halfMCExpand); mc.run(); mc.clean_temps(); MeshData meshData = new MeshData(); meshData.vertices = VertexToVector3Vertices(mc.vertices, mc.nverts(), mapData.offset + addOffset, vertexIncrement); meshData.normals = VertexToVector3Normals(mc.vertices, mc.nverts()); //meshData.uv = NormalsToUVs(mesh.normals); meshData.uv = VerticesToUVs(meshData.vertices); meshData.triangles = TrianglesToInt(mc.triangles, mc.ntrigs()); return(meshData); }
private CelestialBodyColorMap GenerateCelestialBodyColorMap(int width, int height, ColorSettings colorSettings, NoiseMapData noiseMapData) { Color[][] layerColorMaps = new Color[colorSettings.layers][]; Color[] nightGlowColorMap = new Color[width * height]; for (int i = 0; i < layerColorMaps.Length; i++) { layerColorMaps[i] = new Color[width * height]; } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { float noiseValue = Mathf.InverseLerp(noiseMapData.minValue, noiseMapData.maxValue, noiseMapData.noiseValues[x, y]); float minRange = 0; float maxRange = 1; int index = 0; Gradient gradient; float tones = 1; float toneFalloff = 1; bool isLand = false; if (noiseValue >= colorSettings.waterLevel) { if (colorSettings.waterLevel > 0) { minRange = 1 - colorSettings.waterLevel; } gradient = colorSettings.landGradient; tones = colorSettings.landTones; isLand = true; } else { maxRange = colorSettings.waterLevel; gradient = colorSettings.waterGradient; tones = colorSettings.waterTones; toneFalloff = colorSettings.toneFalloff; nightGlowColorMap[x + y * width] = Color.white; } float normalisedValue = Mathf.InverseLerp(minRange, maxRange, noiseValue); if (toneFalloff != 1) { normalisedValue = Mathf.Pow(normalisedValue, toneFalloff); } if (colorSettings.reducedTones) { normalisedValue = Mathf.Round(normalisedValue * tones) / tones; } if (isLand) { index = (int)Mathf.Round(normalisedValue * (layerColorMaps.GetLength(0) - 1)); } Color textureColor; if (colorSettings.useColor) { textureColor = gradient.Evaluate(normalisedValue); } else { textureColor = new Color(normalisedValue, normalisedValue, normalisedValue); } for (int i = 0; i < 1 + index; i++) { layerColorMaps[i][x + y * width] = textureColor; } } } CelestialBodyColorMap celestialBodyData = new CelestialBodyColorMap(); celestialBodyData.layerColorMaps = layerColorMaps; celestialBodyData.nightGlowColorMap = nightGlowColorMap; return(celestialBodyData); }
public void GeneratePreview() { if (previewMode == PreviewMode.WholeSphere) { allSphereChunks.SetActive(false); meshFilter.gameObject.SetActive(true); noiseMap = NoiseMapGenerator.GetNoiseMap3D(diameter + 1, diameter + 1, diameter + 1, offset, noiseSettings); NoiseMapData mapData = new NoiseMapData(noiseMap, offset); Mesh mesh = MeshGenerator.GenerateSphereMesh(mapData, sphereMeshSettings, lod).GetMesh(); meshFilter.sharedMesh = mesh; UpdateReferenceSphere(); UpdateReferencePlanes(); } else if (previewMode == PreviewMode.SingleChunk) { allSphereChunks.SetActive(false); meshFilter.gameObject.SetActive(true); noiseMap = NoiseMapGenerator.GetNoiseMap3D(sphereMeshSettings.chunkSize + 1, sphereMeshSettings.chunkSize + 1, sphereMeshSettings.chunkSize + 1, offset, noiseSettings); NoiseMapData mapData = new NoiseMapData(noiseMap, offset); Mesh mesh = MeshGenerator.GenerateSphereChunkMesh(mapData, sphereMeshSettings, lod).GetMesh(); meshFilter.sharedMesh = mesh; } else if (previewMode == PreviewMode.AllChunks) { meshFilter.gameObject.SetActive(false); allSphereChunks.SetActive(true); DeleteChunks(); int chunkRadius = Mathf.CeilToInt(sphereMeshSettings.radius / sphereMeshSettings.chunkSize); if (noiseSettings.isNormalized) { chunkRadius += Mathf.Max(Mathf.RoundToInt(sphereMeshSettings.noiseHeightScale * (1 - noiseSettings.normShift)) / sphereMeshSettings.chunkSize, 2); } else { chunkRadius += Mathf.Max(Mathf.RoundToInt(sphereMeshSettings.noiseHeightScale * 1.5f) / sphereMeshSettings.chunkSize, 2); } if (chunkRadius % 2 == 1) { chunkRadius--; } // Save the old offset so we can change it back later for (int z = -chunkRadius; z < chunkRadius; z++) { for (int y = -chunkRadius; y < chunkRadius; y++) { for (int x = -chunkRadius; x < chunkRadius; x++) { Vector3 chunkOffset = new Vector3(x * sphereMeshSettings.chunkSize, y * sphereMeshSettings.chunkSize, z * sphereMeshSettings.chunkSize); GameObject newChunk = new GameObject("Chunk: " + chunkOffset.x + ", " + chunkOffset.y + ", " + chunkOffset.z); newChunk.transform.SetParent(allSphereChunks.transform); noiseMap = NoiseMapGenerator.GetNoiseMap3D(sphereMeshSettings.chunkSize + 1, sphereMeshSettings.chunkSize + 1, sphereMeshSettings.chunkSize + 1, chunkOffset, noiseSettings); NoiseMapData mapData = new NoiseMapData(noiseMap, chunkOffset); // Mesh mesh = MeshGenerator.GenerateSphereChunkMesh(mapData, sphereMeshSettings, lod).GetMesh(); // newChunk.AddComponent <MeshFilter>().sharedMesh = mesh; newChunk.AddComponent <MeshRenderer>().sharedMaterial = material; } } } } else if (previewMode == PreviewMode.Threaded) { MyStopwatch.stopwatch.Start(); meshFilter.gameObject.SetActive(false); allSphereChunks.SetActive(true); DeleteChunks(); //int chunkRadius = Mathf.CeilToInt(sphereMeshSettings.radius / sphereMeshSettings.chunkSize) + 2; //if (noiseSettings.isNormalized) //{ // chunkRadius += Mathf.Max(Mathf.RoundToInt(sphereMeshSettings.noiseHeightScale * (1 - noiseSettings.normShift)) / sphereMeshSettings.chunkSize, 2); //} //else //{ // chunkRadius += Mathf.Max(Mathf.RoundToInt(sphereMeshSettings.noiseHeightScale * 1.5f) / sphereMeshSettings.chunkSize, 2); //} int chunkRadius = viewDistance / sphereMeshSettings.chunkSize; int chunksCreated = 0; for (int z = -chunkRadius; z < chunkRadius; z++) { for (int y = Mathf.FloorToInt(sphereMeshSettings.radius / sphereMeshSettings.chunkSize) - chunkRadius; y < Mathf.CeilToInt(sphereMeshSettings.radius / sphereMeshSettings.chunkSize) + 2; y++) { for (int x = -chunkRadius; x < chunkRadius; x++) { Vector3 chunkOffset = new Vector3(x * sphereMeshSettings.chunkSize, y * sphereMeshSettings.chunkSize, z * sphereMeshSettings.chunkSize); new TerrainChunk(chunkOffset, allSphereChunks.transform, noiseSettings, sphereMeshSettings, material, allSphereChunks.transform); chunksCreated++; } } } //if (chunkRadius % 2 == 1) //{ // chunkRadius--; //} //int chunksCreated = 0; //for (int z = -chunkRadius; z < chunkRadius; z++) //{ // for (int y = -chunkRadius; y < chunkRadius; y++) // { // for (int x = -chunkRadius; x < chunkRadius; x++) // { // Vector3 chunkOffset = new Vector3(x * sphereMeshSettings.chunkSize, y * sphereMeshSettings.chunkSize, z * sphereMeshSettings.chunkSize); // new TerrainChunk(chunkOffset, sphereMeshSettings.chunkSize, allSphereChunks.transform, noiseSettings, sphereMeshSettings, material, vertexIncrement); // chunksCreated++; // } // } //} MyStopwatch.s = string.Format("{0}", chunksCreated); } UpdateReferenceSphere(); UpdateReferencePlanes(); }