public void AddAdjacentPolygon(GraphPolygon adj) { if (!AdjacentPolygons.Contains(adj)) { AdjacentPolygons.Add(adj); UpdateNeighbours(); } }
public void AddWaterNeighbour(GraphPolygon wn) { if (!WaterNeighbours.Contains(wn)) { WaterNeighbours.Add(wn); UpdateNeighbours(); } }
public static void DoTurnRandomPolygonToWater(PolygonMapGenerator PMG) { List <GraphPolygon> landPolygons = PMG.Polygons.Where(x => !x.IsWater).ToList(); if (landPolygons.Count == 0) { return; } GraphPolygon newWater = landPolygons[UnityEngine.Random.Range(0, landPolygons.Count)]; TurnPolygonToWater(newWater); }
public static void DoExpandOcean(PolygonMapGenerator PMG) { List <GraphPolygon> shorePolygons = PMG.Polygons.Where(x => !x.IsWater && x.IsNextToWater).ToList(); if (shorePolygons.Count == 0) { return; } GraphPolygon newWater = shorePolygons[UnityEngine.Random.Range(0, shorePolygons.Count)]; TurnPolygonToWater(newWater); }
public static void DoExpandLand(PolygonMapGenerator PMG) { List <GraphPolygon> waterShorePolygons = PMG.Polygons.Where(x => !x.IsEdgePolygon && !x.AdjacentPolygons.Any(y => y.IsEdgePolygon) && x.IsWater && x.IsNextToLand()).ToList(); // When there is no land yet, just convert a random polygon to land if (waterShorePolygons.Count == 0) { waterShorePolygons = PMG.Polygons.Where(x => !x.IsEdgePolygon).ToList(); } GraphPolygon newLand = waterShorePolygons[UnityEngine.Random.Range(0, waterShorePolygons.Count)]; TurnPolygonToLand(newLand); }
private static void IdentifyWaterBodies(PolygonMapGenerator PMG) { PMG.WaterBodies = new List <List <GraphPolygon> >(); List <GraphPolygon> polygonsWithoutWaterBody = new List <GraphPolygon>(); polygonsWithoutWaterBody.AddRange(PMG.Polygons.Where(x => x.IsWater && !x.IsOuterPolygon)); while (polygonsWithoutWaterBody.Count > 0) { List <GraphPolygon> waterBodyPolygons = new List <GraphPolygon>(); Queue <GraphPolygon> polygonsToAdd = new Queue <GraphPolygon>(); polygonsToAdd.Enqueue(polygonsWithoutWaterBody[0]); while (polygonsToAdd.Count > 0) { GraphPolygon polygonToAdd = polygonsToAdd.Dequeue(); waterBodyPolygons.Add(polygonToAdd); foreach (GraphPolygon neighbourPolygon in polygonToAdd.AdjacentPolygons.Where(x => x.IsWater && !x.IsOuterPolygon)) { if (!waterBodyPolygons.Contains(neighbourPolygon) && !polygonsToAdd.Contains(neighbourPolygon)) { polygonsToAdd.Enqueue(neighbourPolygon); } } } bool isLake = waterBodyPolygons.Count < 5; PMG.WaterBodies.Add(waterBodyPolygons); // Add outer ocean to ocean if (!isLake) { foreach (GraphPolygon poly in PMG.Polygons.Where(x => x.IsOuterPolygon)) { waterBodyPolygons.Add(poly); } } foreach (GraphPolygon poly in waterBodyPolygons) { polygonsWithoutWaterBody.Remove(poly); } } }
private static void TurnPolygonToLand(GraphPolygon p) { if (p.IsWater) { p.IsWater = false; foreach (GraphNode n in p.Nodes) { n.SetType(); } foreach (GraphConnection c in p.Connections) { c.SetType(); } foreach (GraphPolygon pn in p.AdjacentPolygons) { pn.IsNextToWater = pn.AdjacentPolygons.Any(x => x.IsWater); } } }
private static void TurnPolygonToWater(GraphPolygon p) { if (!p.IsWater) { p.IsWater = true; foreach (GraphNode n in p.Nodes) { n.SetType(); } foreach (GraphConnection c in p.Connections) { c.SetType(); } foreach (GraphPolygon pn in p.AdjacentPolygons) { pn.IsNextToWater = true; } } }
private static void IdentifyLandmasses(PolygonMapGenerator PMG) { // Identify landmasses PMG.Landmasses = new List <List <GraphPolygon> >(); List <GraphPolygon> polygonsWithoutLandmass = new List <GraphPolygon>(); polygonsWithoutLandmass.AddRange(PMG.Polygons.Where(x => !x.IsWater)); while (polygonsWithoutLandmass.Count > 0) { List <GraphPolygon> landmassPolygons = new List <GraphPolygon>(); Queue <GraphPolygon> polygonsToAdd = new Queue <GraphPolygon>(); polygonsToAdd.Enqueue(polygonsWithoutLandmass[0]); while (polygonsToAdd.Count > 0) { GraphPolygon polygonToAdd = polygonsToAdd.Dequeue(); landmassPolygons.Add(polygonToAdd); foreach (GraphPolygon neighbourPolygon in polygonToAdd.AdjacentPolygons.Where(x => !x.IsWater)) { if (!landmassPolygons.Contains(neighbourPolygon) && !polygonsToAdd.Contains(neighbourPolygon)) { polygonsToAdd.Enqueue(neighbourPolygon); } } } PMG.Landmasses.Add(landmassPolygons); foreach (GraphPolygon poly in landmassPolygons) { polygonsWithoutLandmass.Remove(poly); } } foreach (List <GraphPolygon> landmass in PMG.Landmasses) { foreach (GraphPolygon polygon in landmass) { polygon.Landmass = landmass; } } }
public static Biome GetBiome(GraphPolygon polygon) { int Temperature = polygon.Temperature; int Precipitation = polygon.Precipitation; if (Temperature < -8) { return(Biome.Ice); } else if (Temperature < -3) { return(Biome.Tundra); } else if (Temperature < 1) { if (Precipitation < 200) { return(Biome.Grassland); } else if (Precipitation < 300) { return(Biome.Shrubland); } else { return(Biome.Tundra); } } else if (Temperature < 8) { if (Precipitation < 300) { return(Biome.Grassland); } else if (Precipitation < 400) { return(Biome.Shrubland); } else { return(Biome.BorealForest); } } else if (Temperature < 14) { if (Precipitation < 500) { return(Biome.Grassland); } else if (Precipitation < 800) { return(Biome.Shrubland); } else if (Precipitation < 1700) { return(Biome.Temperate); } else { return(Biome.TemperateRainForest); } } else if (Temperature < 19) { if (Precipitation < 600) { return(Biome.Grassland); } else if (Precipitation < 1100) { return(Biome.Shrubland); } else if (Precipitation < 2000) { return(Biome.Temperate); } else { return(Biome.TemperateRainForest); } } else if (Temperature < 23) { if (Precipitation < 700) { return(Biome.Desert); } else if (Precipitation < 1300) { return(Biome.Shrubland); } else if (Precipitation < 2200) { return(Biome.Temperate); } else { return(Biome.TemperateRainForest); } } else { if (Precipitation < 800) { return(Biome.Desert); } else if (Precipitation < 1400) { return(Biome.Savanna); } else if (Precipitation < 2600) { return(Biome.Tropical); } else { return(Biome.TropicalRainForest); } } }
/// <summary> /// Returns true if two polygons have the same nodes. /// </summary> public bool HasSameNodesAs(GraphPolygon otherPoly) { int[] polyNodeIds = Nodes.OrderBy(x => x.Id).Select(x => x.Id).ToArray(); int[] otherPolyNodeIds = otherPoly.Nodes.OrderBy(x => x.Id).Select(x => x.Id).ToArray(); return(Enumerable.SequenceEqual(polyNodeIds, otherPolyNodeIds)); }
public static River CreateRiverObject(GraphPath riverPath, PolygonMapGenerator PMG) { //Debug.Log("Creating mesh for river with " + riverPath.Nodes.Count + " points"); // Calculate vertices of river polygon List <Vector2> polygonVerticesHalf1 = new List <Vector2>(); List <Vector2> polygonVerticesHalf2 = new List <Vector2>(); for (int i = 1; i < riverPath.Nodes.Count - 1; i++) { Vector2 startPoint = riverPath.Nodes[i - 1].Vertex; Vector2 thisPoint = riverPath.Nodes[i].Vertex; Vector2 nextPoint = riverPath.Nodes[i + 1].Vertex; float startWidth = riverPath.Nodes[i - 1].RiverWidth; float endWidth = riverPath.Nodes[i].RiverWidth; //Debug.Log("River point " + i + ": startWidth = " + startWidth + ", endWidth = " + endWidth); if (i == 1) // Add two starting points { Vector2 rotatedVector = GeometryFunctions.RotateVector((thisPoint - startPoint).normalized * startWidth, 90); polygonVerticesHalf1.Add(startPoint + rotatedVector); polygonVerticesHalf2.Add(startPoint - rotatedVector); } polygonVerticesHalf1.Add(GeometryFunctions.GetOffsetIntersection(startPoint, thisPoint, nextPoint, startWidth, endWidth, true)); polygonVerticesHalf2.Add(GeometryFunctions.GetOffsetIntersection(startPoint, thisPoint, nextPoint, startWidth, endWidth, false)); if (i == riverPath.Nodes.Count - 2) // Add two ending points (calculate river delta by taking intersecion between river and shoreline { GraphNode lastNode = riverPath.Nodes.Last(); List <GraphConnection> shoreDelta = lastNode.Connections.Where(x => x.Type == BorderType.Shore).ToList(); List <GraphNode> riverDeltaPoints = new List <GraphNode>(); foreach (GraphConnection delta in shoreDelta) { if (delta.StartNode == lastNode) { riverDeltaPoints.Add(delta.EndNode); } else { riverDeltaPoints.Add(delta.StartNode); } } Vector2 endPoint1, endPoint2; // BUG: this method doesn't work 100% GraphPolygon firstPolygon = riverPath.Nodes[i].Polygons.FirstOrDefault(x => GeometryFunctions.IsPointInPolygon4(x.Nodes.Select(x => x.Vertex).ToList(), polygonVerticesHalf1.Last())); if (firstPolygon == null) { throw new Exception("Couldn't find direction of river delta. is river too short? length = " + riverPath.Nodes.Count); } bool addDeltaMidPoint = true; if (riverDeltaPoints[0].Polygons.Contains(firstPolygon)) { endPoint1 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[0].Vertex, endWidth, 0f, true); endPoint2 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[1].Vertex, endWidth, 0f, false); if (!GeometryFunctions.IsPointOnLineSegment(endPoint1, riverDeltaPoints[0].Vertex, lastNode.Vertex)) { endPoint1 = lastNode.Vertex; addDeltaMidPoint = false; } if (!GeometryFunctions.IsPointOnLineSegment(endPoint2, riverDeltaPoints[1].Vertex, lastNode.Vertex)) { endPoint2 = lastNode.Vertex; addDeltaMidPoint = false; } } else { endPoint1 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[1].Vertex, endWidth, 0f, true); endPoint2 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[0].Vertex, endWidth, 0f, false); if (!GeometryFunctions.IsPointOnLineSegment(endPoint1, riverDeltaPoints[1].Vertex, lastNode.Vertex)) { endPoint1 = lastNode.Vertex; addDeltaMidPoint = false; } if (!GeometryFunctions.IsPointOnLineSegment(endPoint2, riverDeltaPoints[0].Vertex, lastNode.Vertex)) { endPoint2 = lastNode.Vertex; addDeltaMidPoint = false; } } polygonVerticesHalf1.Add(endPoint1); if (addDeltaMidPoint) { polygonVerticesHalf1.Add(lastNode.Vertex); } polygonVerticesHalf2.Add(endPoint2); } } polygonVerticesHalf2.Reverse(); List <Vector2> polygonVertices = polygonVerticesHalf1; polygonVertices.AddRange(polygonVerticesHalf2); List <Vector2> polygonVerticesList = polygonVertices.ToList(); if (GeometryFunctions.IsClockwise(polygonVerticesList)) { polygonVerticesList.Reverse(); } // Create object GameObject riverObject = MeshGenerator.GeneratePolygon(polygonVerticesList, PMG, layer: PolygonMapGenerator.LAYER_RIVER); River river = riverObject.AddComponent <River>(); river.Init(riverPath.Nodes.Select(x => x.BorderPoint).ToList(), riverPath.Connections.Select(x => x.Border).ToList(), riverPath.Polygons.Select(x => x.Region).ToList()); riverObject.GetComponent <MeshRenderer>().material.color = Color.red; riverObject.name = "River"; return(river); }