public void MeshAndVisualize(LandMap landMap) { var timer = Stopwatch.StartNew(); CreateZonesHandle(landMap.Layout.Zones); ChunkGO.Clear(); //var mesher = new InfluenceMesher(this); //var mesher = new ColorMesher(this); var mesherSettings = GetComponent <MesherSettings>(); var mesher = new TextureMesher(this, mesherSettings); //var mesh = mesher.Generate(landMap.Map[Vector2i.Zero], landMap.Map); //var go = ChunkGO.Create(landMap.Map[Vector2i.Zero], mesh); foreach (var chunk in landMap.Map) { var mesh = mesher.Generate(chunk.Value, landMap.Map); var go = ChunkGO.Create(chunk.Value, mesh); go.CreateFlora(this, chunk.Value.Flora); go.CreateStones(this, chunk.Value.Stones); } mesher.ReleaseRenderTextures(); timer.Stop(); Debug.LogFormat("Mesh generation {0} ms total", timer.ElapsedMilliseconds); Debug.LogFormat("Mesh generation timings: mesh {0} ms, texture {1} ms, {2} ops", mesher.MeshTimer.AvgTimeMs, mesher.TextureTimer.AvgTimeMs, mesher.TextureTimer.SamplesCount); }
void ILandMapEffector.Effect(LandMap landMap) { if (level <= 1) { return; } for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { var nextValue = landMap.GetHeight(x, y); var nextValueCount = 0; for (var xRange = Math.Max(x - level, 0); xRange < Math.Min(x + level, LandMap.Size); xRange++) { for (var yRange = Math.Max(y - level, 0); yRange < Math.Min(y + level, LandMap.Size); yRange++, nextValueCount++) { var subX = x - xRange; var subY = y - yRange; if (!(Math.Sqrt(subX * subX + subY * subY) <= level)) { continue; } nextValue += landMap.GetHeight(xRange, yRange); } } var finalValue = nextValue / nextValueCount; landMap.SetHeight(x, y, finalValue); } } }
public void GenerateIsland() { if (useRandomSeed) { seed = System.DateTime.Now.ToString(); } int seedHash = seed.GetHashCode(); System.Random pseudoRandom = new System.Random(seedHash); map = new LandMap(islandData.maxWidth, islandData.maxHeight); // Fill the map randomly with 0s and 1s based on percentage fill map.RandomFillMap(ref pseudoRandom, islandData.randomFillPercent); // Smooth the map 5 times map.SmoothMap(5); // Create separate islands PartitionIslands(); if (shouldElevate) { foreach (IsleInfo island in islands) { island.surfaceMeshRegion.CalculateGradientMap(); } ElevationGenerator elevGen = GetComponent <ElevationGenerator> (); elevGen.elevateSurface(islands, islandData.altitude, islandData.mountainCurve, surfaceNoiseData, seedHash, 0); // elevate hills on the surface elevGen.elevateSurface(islands, -islandData.stalactite, islandData.bellyCurve, undersideNoiseData, seedHash, 2); // extend stakes at surface below } SetColliders(); PlacementGenerator placement = GetComponent <PlacementGenerator> (); if (placement && decorateTerrain) { placement.GeneratePlacement(islands, ref pseudoRandom); } if (flatShading) { foreach (IsleInfo island in islands) { for (int surfaceIndex = 0; surfaceIndex < 3; surfaceIndex++) { MeshFilter mf = island.GetSurfaceMesh(surfaceIndex); float oldVertCount = mf.sharedMesh.vertexCount; mf.sharedMesh = FlatShade.DuplicateSharedVertex(mf.sharedMesh); float newVertCount = mf.sharedMesh.vertexCount; //Debug.Log (mf.transform.parent.name + "." + mf.transform.name + " new vertices are at " + (newVertCount / oldVertCount * 100) + "% with " + newVertCount + " verts."); } } } }
void ILandMapEffector.Effect(LandMap landMap) { for (var drop = 0; drop < drops; drop++) { var x = Mathf.FloorToInt(LandMap.RandomValue * LandMap.Size); var y = Mathf.FloorToInt(LandMap.RandomValue * LandMap.Size); Deposit(landMap, x, y); } }
/// <summary> /// Generate land /// </summary> /// <param name="map"></param> public LandMap Generate(LandMap map) { foreach (var zoneMarkup in _land.Zones.Where(z => z.Cell.IsClosed)) { ZoneGenerator generator = null; if (zoneMarkup.Type == ZoneType.Hills) { generator = new HillsGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Lake) { generator = new LakeGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Forest) { generator = new ForestGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Mountains) { generator = new MountainsGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Snow) { generator = new SnowGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type >= ZoneType.Hills && zoneMarkup.Type <= ZoneType.Lake) { generator = new DefaultGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type >= ZoneType.Influence1 && zoneMarkup.Type <= ZoneType.Influence8) { generator = new FlatGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Checkboard) { generator = new CheckboardGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Cone) { generator = new ConeGenerator(zoneMarkup, _land, _settings); } else if (zoneMarkup.Type == ZoneType.Slope) { generator = new SlopeGenerator(zoneMarkup, _land, _settings); } if (generator != null) { var zoneMap = generator.Generate(); map.Add(zoneMap); } } return(map); }
void ILandMapEffector.Effect(LandMap landMap) { for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { var fbm = fBM(x, y, octaves, lacunarity, gain); var value = landMap.GetHeight(x, y); landMap.SetHeight(x, y, fbm + value); } } }
void ILandMapEffector.Effect(LandMap landMap) { for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { var voronoi = Voronoi(x, y, u, v); var value = landMap.GetHeight(x, y); landMap.SetHeight(x, y, voronoi + value); } } }
void ILandMapEffector.Effect(LandMap landMap) { var heightMap = LandMapUtility.CreateTexture(LandMap.TextureSize, "HeightMap", FilterMode.Bilinear, format); for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { heightMap.SetPixel(x, y, Brightness(LandMap.TextureSize, landMap.GetHeight(x, y))); } } heightMap.Apply(); HeightMap = heightMap; }
void ILandMapEffector.Effect(LandMap landMap) { var random = Random.Range(-1000f, 1000f); for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { var xSample = random + (float)x / LandMap.Size * noiseScale; var ySample = random + (float)y / LandMap.Size * noiseScale; var noiseValue = OctavePerlin(xSample, ySample); var value = landMap.GetHeight(x, y); landMap.SetHeight(x, y, noiseValue + value); } } }
public LandMap GenerateMap(ILandSettings settings) { var time = Stopwatch.StartNew(); //Land = new Land(Layout, settings); //Generate land's chunks var map = new LandMap(settings, LandLayout); var landGenerator = new LandGenerator(LandLayout, settings); Map = landGenerator.Generate(map); time.Stop(); //Debug.Log(Land.GetStaticstics()); Debug.Log(string.Format("Generate map {0} ms", time.ElapsedMilliseconds)); return(Map); }
void ILandMapEffector.Effect(LandMap landMap) { var random = Random.Range(-1000f, 1000f); for (var y = 0; y < LandMap.Size; y++) { for (var x = 0; x < LandMap.Size; x++) { var xSample = random + (float)x / LandMap.Size * noiseScale; var ySample = random + (float)y / LandMap.Size * noiseScale; var noise = Mathf.PerlinNoise(xSample, ySample); if (noise <= rounding) { noise = 0; } var value = landMap.GetHeight(x, y); landMap.SetHeight(x, y, noise + value); } } }
public void Effect(LandMap landMap) { var heightMap = lmHeightMap.HeightMap; if (LandMap.TextureSize != size) { heightMap = LandMapUtility.Resize(heightMap, size); } var halfSize = Mathf.CeilToInt((float)size / 2); var verticesSize = halfSize * halfSize; var triangles = new int[(verticesSize - (size - 1)) * 6]; var vertices = new Vector3[verticesSize]; var uv = new Vector2[verticesSize]; var vert = 0; var tri = 0; for (var i = 0; i < halfSize; i++) { for (var j = 0; j < halfSize; j++, ++vert) { //vertices[vert] = new Vector3(i, (range - GetHeight(j, i)) / range * height / 2, j); vertices[vert] = new Vector3(i, heightMap.GetPixel(i, j).grayscale *height / 3, j); if (i == 0 || j == 0) { continue; } var addIj = halfSize * i + j; var subIj = halfSize * (i - 1) + j; Increment(addIj); Increment(addIj - 1); Increment(subIj - 1); Increment(subIj - 1); Increment(subIj); Increment(addIj); } } for (var i = 0; i < verticesSize; i++) { uv[i] = new Vector2(vertices[i].x, vertices[i].z); } var mesh = new Mesh { vertices = vertices, triangles = triangles, uv = uv, name = "LandMap" }; mesh.RecalculateBounds(); mesh.RecalculateTangents(); mesh.RecalculateNormals(); mesh.Optimize(); LandMapMesh = mesh; void Increment(int value) { triangles[tri] = value; tri++; } }
public Combine(LandMap other) => this.other = other;
void GenerateInEditor() { if (!Application.isPlaying) { finished = false; if (useRandomSeed) { seed = DateTime.Now.ToString(); } Random.State oldState = Random.state; int seedHash = seed.GetHashCode(); Random.InitState(seedHash); for (int i = 0; i < randCol.Length; i++) { randCol[i] = Random.ColorHSV(0, 1, 0, 1, 0.5f, 1); } map = new LandMap(islandData.maxWidth, islandData.maxHeight); // Fill the map randomly with 0s and 1s based on percentage fill map.RandomFillMap(islandData.randomFillPercent); // Mold to the base shape if (islandData.baseShape) { map.makeBaseShape(islandData.baseShape); } // Smooth the map 5 times map.SmoothMap(5); meshGen = GetComponent <IslandMeshGenerator> (); vertDatabase.Clear(); vertDatabase.tileSize = islandData.tileSize; // Find separated regions to form an island List <MapRegion> regions = map.GetRegions(); // Create separate islands SeparateIslands(regions); clk.Start(); vertDatabase.SetCoordDB(); Debug.Log("Indexing takes " + clk.Elapsed() + " seconds."); if (shouldElevate) { int highestPeak = 0; foreach (IsleInfo island in islands) { int peak = island.surfaceMeshDetail.localPeak; highestPeak = peak > highestPeak ? peak : highestPeak; } foreach (IsleInfo island in islands) { island.surfaceMeshDetail.NormalizeGradientMap(highestPeak); } vertDatabase.SetVerticesInlandPos(islands, islandData.mountainCurve); ElevationGenerator elevGen = GetComponent <ElevationGenerator> (); elevGen.elevateSurface(islands, islandData.altitude, islandData.mountainCurve, surfaceNoiseData, seedHash, 0, vertDatabase); // elevate hills on the surface elevGen.elevateSurface(islands, -islandData.stalactite, islandData.bellyCurve, undersideNoiseData, seedHash, 2, vertDatabase); // extend stakes at surface below } clk.Start(); int zoneNum = DoClustering(regions, map.spots, vertDatabase, clusterAnalysis, seedHash); Debug.Log("Clustering takes " + clk.Elapsed() + " seconds."); // Find strategic locations in each region List <MapRegion> zones = map.GetZones(zoneNum); SpliceTerritory(zones); SetColliders(); PlacementGenerator placement = GetComponent <PlacementGenerator> (); if (placement && decorateTerrain) { placement.GenerateTrees(islands); placement.GenerateSectorsContent(sectors, vertDatabase); } else if (placement) { //placement.GeneratePlacements (islands); placement.GenerateSectorsContent(sectors, vertDatabase); } if (flatShading) { foreach (IsleInfo island in islands) { for (int surfaceIndex = 0; surfaceIndex < 3; surfaceIndex++) { MeshFilter mf = island.GetSurfaceMesh(surfaceIndex); float oldVertCount = mf.sharedMesh.vertexCount; mf.sharedMesh = FlatShade.DuplicateSharedVertex(mf.sharedMesh); float newVertCount = mf.sharedMesh.vertexCount; //Debug.Log (mf.transform.parent.name + "." + mf.transform.name + " new vertices are at " + (newVertCount / oldVertCount * 100) + "% with " + newVertCount + " verts."); } } } Random.state = oldState; } }
private void Deposit(LandMap landMap, int x, int y) { var c = 0f; var v = 1.05f; const float minSlope = 1.15f; const float maxVelocity = 10f; for (var iteration = 0; iteration < iterations; iteration++) { v = Mathf.Min(v, maxVelocity); var value = landMap.GetHeight(x, y); float[] nv = { landMap.GetHeight(x, y - 1), landMap.GetHeight(x, y + 1), landMap.GetHeight(x + 1, y), landMap.GetHeight(x - 1, y) }; var minIndex = IndexOfMinimum(nv); if (!(nv[minIndex] < value)) { continue; } var slope = Mathf.Min(minSlope, value - nv[minIndex]); var vtc = depositionSpeed * v * slope; if (c > carryingCapacity) { c -= vtc; landMap.SetHeight(x, y, landMap.GetHeight(x, y) + vtc); } else { if (c + vtc > carryingCapacity) { var delta = c + vtc - carryingCapacity; c += delta; landMap.SetHeight(x, y, landMap.GetHeight(x, y) + delta); } else { c += vtc; landMap.SetHeight(x, y, landMap.GetHeight(x, y) - vtc); } } switch (minIndex) { case 0: y -= 1; break; case 1: y += 1; break; case 2: x += 1; break; case 3: x -= 1; break; } if (x > LandMap.MaxSize) { x = LandMap.Size; } if (x < 0) { x = 0; } if (y > LandMap.MaxSize) { y = LandMap.Size; } if (y < 0) { y = 0; } } int IndexOfMinimum(IReadOnlyList <float> array) { var index = 0; var minValue = array[0]; for (var i = 0; i < 3; i++) { if (!(array[i] < minValue)) { continue; } minValue = array[i]; index = i; } return(index); } }