GameObject GenerateProvinceRegionSurface(int provinceIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation, bool temporary) { if (provinceIndex < 0 || provinceIndex >= provinces.Length) { return(null); } if (provinces [provinceIndex].regions == null) { ReadProvincePackedString(provinces [provinceIndex]); } if (provinces [provinceIndex].regions == null || regionIndex < 0 || regionIndex >= provinces [provinceIndex].regions.Count) { return(null); } Province province = provinces [provinceIndex]; Region region = province.regions [regionIndex]; if (!temporary) { region.customMaterial = material; region.customTextureOffset = textureOffset; region.customTextureRotation = textureRotation; region.customTextureScale = textureScale; UpdateSurfaceCount(); } // Triangulate to get the polygon vertex indices Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.latlon); if (_enableProvinceEnclaves && regionIndex == province.mainRegionIndex) { ProvinceSubstractProvinceEnclaves(provinceIndex, region, poly); } // Antarctica, Saskatchewan (Canada), British Columbia (Canada), Krasnoyarsk (Russia) - special cases due to its geometry float step = _frontiersDetail == FRONTIERS_DETAIL.High ? 2f : 5f; if (steinerPoints == null) { steinerPoints = new List <TriangulationPoint> (1000); } else { steinerPoints.Clear(); } float x0 = region.latlonRect2D.min.x + step / 2f; float x1 = region.latlonRect2D.max.x - step / 2f; float y0 = region.latlonRect2D.min.y + step / 2f; float y1 = region.latlonRect2D.max.y - step / 2f; for (float x = x0; x < x1; x += step) { for (float y = y0; y < y1; y += step) { float xp = x + UnityEngine.Random.Range(-0.0001f, 0.0001f); float yp = y + UnityEngine.Random.Range(-0.0001f, 0.0001f); if (region.Contains(xp, yp)) { steinerPoints.Add(new TriangulationPoint(xp, yp)); // GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); // obj.transform.SetParent(WorldMapGlobe.instance.transform, false); // obj.transform.localScale = Vector3.one * 0.01f; // obj.transform.localPosition = Conversion.GetSpherePointFromLatLon(new Vector2(x,y)) * 1.01f; } } } if (steinerPoints.Count > 0) { poly.AddSteinerPoints(steinerPoints); } P2T.Triangulate(poly); int flip1, flip2; if (_earthInvertedMode) { flip1 = 2; flip2 = 1; } else { flip1 = 1; flip2 = 2; } int triCount = poly.Triangles.Count; Vector3[] revisedSurfPoints = new Vector3[triCount * 3]; for (int k = 0; k < triCount; k++) { DelaunayTriangle dt = poly.Triangles [k]; revisedSurfPoints [k * 3] = Conversion.GetSpherePointFromLatLon(dt.Points [0].X, dt.Points [0].Y); revisedSurfPoints [k * 3 + flip1] = Conversion.GetSpherePointFromLatLon(dt.Points [1].X, dt.Points [1].Y); revisedSurfPoints [k * 3 + flip2] = Conversion.GetSpherePointFromLatLon(dt.Points [2].X, dt.Points [2].Y); } int revIndex = revisedSurfPoints.Length - 1; // Generate surface mesh int cacheIndex = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex); GameObject surf = Drawing.CreateSurface(SURFACE_GAMEOBJECT, revisedSurfPoints, revIndex, material, region.rect2Dbillboard, textureScale, textureOffset, textureRotation); surf.transform.SetParent(surfacesLayer.transform, false); surf.transform.localPosition = Misc.Vector3zero; if (_earthInvertedMode) { surf.transform.localScale = Misc.Vector3one * 0.998f; } surfaces [cacheIndex] = surf; return(surf); }
void ProvinceSubstractProvinceEnclaves(int provinceIndex, Region region, Poly2Tri.Polygon poly) { List <Region> negativeRegions = new List <Region> (); for (int oc = 0; oc < _countries.Length; oc++) { Country ocCountry = _countries [oc]; if (ocCountry.hidden || ocCountry.provinces == null) { continue; } if (!ocCountry.regionsRect2D.Overlaps(region.latlonRect2D)) { continue; } for (int op = 0; op < ocCountry.provinces.Length; op++) { Province opProvince = ocCountry.provinces [op]; if (opProvince == provinces [provinceIndex] || opProvince.hidden) { continue; } if (opProvince.regions == null) { continue; } if (opProvince.regionsRect2D.Overlaps(region.latlonRect2D, true)) { Region oProvRegion = opProvince.regions [opProvince.mainRegionIndex]; if (region.Contains(oProvRegion)) // just check main region of province for speed purposes { negativeRegions.Add(oProvRegion); } } } } // Collapse negative regions in big holes // Collapse negative regions in big holes for (int nr = 0; nr < negativeRegions.Count - 1; nr++) { for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++) { if (negativeRegions [nr].Intersects(negativeRegions [nr2])) { Clipper clipper = new Clipper(); clipper.AddPath(negativeRegions [nr], PolyType.ptSubject); clipper.AddPath(negativeRegions [nr2], PolyType.ptClip); clipper.Execute(ClipType.ctUnion, negativeRegions [nr]); negativeRegions.RemoveAt(nr2); nr = -1; break; } } } // Substract holes for (int r = 0; r < negativeRegions.Count; r++) { Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(negativeRegions [r].latlon); poly.AddHole(polyHole); } }