Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }