Пример #1
0
        int overlapComparer(MeshRect r1, MeshRect r2)
        {
            float r1MidY = (r1.rect.w + r1.rect.y) * 0.5f;
            float r2MidY = (r2.rect.w + r2.rect.y) * 0.5f;

            if (r2MidY < r1MidY)
            {
                return(-1);
            }
            else if (r2MidY > r1MidY)
            {
                return(1);
            }
            else
            {
                return(0);
            }
//			return (r2.rect.center.y).CompareTo(r1.rect.center.y);
        }
Пример #2
0
        /// <summary>
        /// Draws the province labels for a given country. Note that it will update cached textmesh objects if labels are already drawn. Used internally.
        /// </summary>
        void DrawProvinceLabelsInt(Country country)
        {
            if (!Application.isPlaying || !_showProvinceNames || !gameObject.activeInHierarchy || country == null || country.hidden || provinces == null || country.provinces == null)
            {
                return;
            }

            countryProvincesLabelsShown = country;

            // Set colors
            provLabelsFont.material.color  = _provinceLabelsColor;
            provLabelsShadowMaterial.color = _provinceLabelsShadowColor;

            // Create texts
            GameObject overlay = GetOverlayLayer(true);
            Transform  t       = overlay.transform.Find(OVERLAY_TEXT_PROVINCE_ROOT);

            if (t == null)
            {
                textProvinceRoot = new GameObject(OVERLAY_TEXT_PROVINCE_ROOT);
                if (disposalManager != null)
                {
                    disposalManager.MarkForDisposal(textProvinceRoot);                                        // textProvinceRoot.hideFlags = HideFlags.DontSave;
                }
                textProvinceRoot.layer = overlay.layer;
            }
            else
            {
                textProvinceRoot = t.gameObject;
            }

            if (meshRects == null)
            {
                meshRects = new List <MeshRect> (country.provinces.Length);
            }
            else
            {
                meshRects.Clear();
            }
            float mw = mapWidth;
            float mh = mapHeight;

            for (int p = 0; p < country.provinces.Length; p++)
            {
                Province province = country.provinces[p];
                if (province.regions == null)
                {
                    ReadProvincePackedString(province);
                }
                if (province == null || province.hidden || !province.labelVisible || province.regions == null || province.mainRegionIndex < 0 || province.mainRegionIndex >= province.regions.Count)
                {
                    continue;
                }

                if (_provinceLabelsVisibility == PROVINCE_LABELS_VISIBILITY.Automatic && !_showAllCountryProvinceNames && province != _provinceHighlighted)
                {
                    continue;
                }

                Vector2 center = new Vector2(province.center.x * mapWidth, province.center.y * mh) + province.labelOffset;
                Region  region = province.regions[province.mainRegionIndex];

                // Adjusts province name length
                string provinceName             = province.customLabel != null ? province.customLabel : province.name.ToUpper();
                bool   introducedCarriageReturn = false;
                if (provinceName.Length > 15)
                {
                    int spaceIndex = provinceName.IndexOf(' ', provinceName.Length / 2);
                    if (spaceIndex >= 0)
                    {
                        provinceName             = provinceName.Substring(0, spaceIndex) + "\n" + provinceName.Substring(spaceIndex + 1);
                        introducedCarriageReturn = true;
                    }
                }

                // add caption
                GameObject textObj;
                TextMesh   tm;
                Renderer   tmRenderer;
                TextMesh   tmShadow = null;
                if (province.labelTextMeshGO == null)
                {
                    Color    labelColor = province.labelColorOverride ? province.labelColor : _provinceLabelsColor;
                    Font     customFont = province.labelFontOverride ?? provLabelsFont;
                    Material customLabelShadowMaterial = province.labelFontShadowMaterial ?? provLabelsShadowMaterial;
                    tm      = Drawing.CreateText(provinceName, null, center, customFont, labelColor, _showProvinceLabelsShadow, customLabelShadowMaterial, _provinceLabelsShadowColor, out tmShadow);
                    textObj = tm.gameObject;
                    province.labelTextMesh   = tm;
                    province.labelTextMeshGO = tm.gameObject;
                    tmRenderer = textObj.GetComponent <Renderer>();
                    Bounds bounds = tmRenderer.bounds;
                    province.labelMeshWidth  = bounds.size.x;
                    province.labelMeshHeight = bounds.size.y;
                    province.labelMeshCenter = center;
                    textObj.transform.SetParent(textProvinceRoot.transform, false);
                    textObj.transform.localPosition = center;
                    textObj.layer = textProvinceRoot.gameObject.layer;
                    if (_showProvinceLabelsShadow)
                    {
                        province.labelShadowTextMesh = tmShadow;
                        province.labelShadowTextMesh.gameObject.layer = textObj.layer;
                    }
                }
                else
                {
                    tm      = province.labelTextMesh;
                    textObj = tm.gameObject;
                    textObj.transform.localPosition = center;
                    tmRenderer = textObj.GetComponent <Renderer>();
                }

                float meshWidth  = province.labelMeshWidth;
                float meshHeight = province.labelMeshHeight;

                // adjusts caption
                Rect  rect = new Rect(region.rect2D.xMin * mw, region.rect2D.yMin * mh, region.rect2D.width * mw, region.rect2D.height * mh);
                float absoluteHeight;
                if (province.labelRotation > 0)
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, province.labelRotation);
                    absoluteHeight = Mathf.Min(rect.height * _provinceLabelsSize, rect.width);
                }
                else if (rect.height > rect.width * 1.45f)
                {
                    float angle;
                    if (rect.height > rect.width * 1.5f)
                    {
                        angle = 90;
                    }
                    else
                    {
                        angle = Mathf.Atan2(rect.height, rect.width) * Mathf.Rad2Deg;
                    }
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, angle);
                    absoluteHeight = Mathf.Min(rect.width * _provinceLabelsSize, rect.height);
                }
                else
                {
                    absoluteHeight = Mathf.Min(rect.height * _provinceLabelsSize, rect.width);
                }

                // adjusts scale to fit width in rect
                float adjustedMeshHeight = introducedCarriageReturn ? meshHeight * 0.5f : meshHeight;
                float scale = absoluteHeight / adjustedMeshHeight;
                if (province.labelFontSizeOverride)
                {
                    scale = province.labelFontSize;
                }
                else
                {
                    float desiredWidth = meshWidth * scale;
                    if (desiredWidth > rect.width)
                    {
                        scale = rect.width / meshWidth;
                    }
                    if (adjustedMeshHeight * scale < _provinceLabelsAbsoluteMinimumSize)
                    {
                        scale = _provinceLabelsAbsoluteMinimumSize / adjustedMeshHeight;
                    }
                }

                // stretchs out the caption
                float  displayedMeshWidth  = meshWidth * scale;
                float  displayedMeshHeight = meshHeight * scale;
                string wideName;
                int    times = Mathf.FloorToInt(rect.width * 0.45f / (meshWidth * scale));
                if (times > 10)
                {
                    times = 10;
                }
                if (times > 0)
                {
                    StringBuilder sb     = new StringBuilder();
                    string        spaces = new string(' ', times * 2);
                    for (int c = 0; c < provinceName.Length; c++)
                    {
                        sb.Append(provinceName[c]);
                        if (c < provinceName.Length - 1)
                        {
                            sb.Append(spaces);
                        }
                    }
                    wideName = sb.ToString();
                }
                else
                {
                    wideName = provinceName;
                }

                if (tm.text.Length != wideName.Length)
                {
                    tm.text             = wideName;
                    displayedMeshWidth  = tmRenderer.bounds.size.x * scale;
                    displayedMeshHeight = tmRenderer.bounds.size.y * scale;
                    if (_showProvinceLabelsShadow)
                    {
                        tmShadow.text = wideName;
                    }
                }

                // apply scale
                textObj.transform.localScale = new Vector3(scale, scale, 1);

                // Save mesh rect for overlapping checking
                if (province.labelOffset == Misc.Vector2zero)
                {
                    int      provinceIndex = GetProvinceIndex(province);
                    float    xMin          = center.x - displayedMeshWidth * 0.5f;
                    float    yMin          = center.y - displayedMeshHeight * 0.5f;
                    float    xMax          = xMin + displayedMeshWidth;
                    float    yMax          = yMin + displayedMeshHeight;
                    MeshRect mr            = new MeshRect(provinceIndex, new Vector4(xMin, yMin, xMax, yMax));
//					MeshRect mr = new MeshRect(provinceIndex, new Rect(center.x - displayedMeshWidth * 0.5f, center.y - displayedMeshHeight * 0.5f, displayedMeshWidth, displayedMeshHeight));
                    meshRects.Add(mr);
                }
            }

            // Simple-fast overlapping checking
            int  cont        = 0;
            bool needsResort = true;

            int meshRectsCount = meshRects.Count;

            while (needsResort && ++cont < 10)
            {
                meshRects.Sort(overlapComparer);

                for (int c = 1; c < meshRectsCount; c++)
                {
                    Vector4 r1 = meshRects[c].rect;
                    for (int prevc = c - 1; prevc >= 0; prevc--)
                    {
                        Vector4 r2       = meshRects[prevc].rect;
                        bool    overlaps = !(r2.x > r1.z || r2.z <r1.x || r2.y> r1.w || r2.w < r1.y);
                        if (overlaps)
                        {
                            needsResort = true;
                            int        thisProvinceIndex = meshRects[c].entityIndex;
                            Province   province          = _provinces[thisProvinceIndex];
                            GameObject thisLabel         = province.labelTextMeshGO;

                            // displaces this label
                            float offsety = r1.w - r2.y;
                            offsety = Mathf.Min(province.regions[province.mainRegionIndex].rect2D.height * mh * 0.35f, offsety);
                            thisLabel.transform.localPosition = new Vector3(province.labelMeshCenter.x, province.labelMeshCenter.y - offsety, thisLabel.transform.localPosition.z);
//							r1 = new Rect(thisLabel.transform.localPosition.x - r1.width * 0.5f,
//								thisLabel.transform.localPosition.y - r1.height * 0.5f,
//								r1.width, r1.height);
//							meshRects[c].rect = r1;
                            float width  = r1.z - r1.x;
                            float height = r1.w - r1.y;
                            float xMin   = thisLabel.transform.localPosition.x - width * 0.5f;
                            float yMin   = thisLabel.transform.localPosition.y - height * 0.5f;
                            float xMax   = xMin + width;
                            float yMax   = yMin + height;
                            r1 = new Vector4(xMin, yMin, xMax, yMax);
                            meshRects [c].rect = r1;
                        }
                    }
                }
            }

            // Adjusts parent
            textProvinceRoot.transform.SetParent(overlay.transform, false);
            textProvinceRoot.transform.localPosition = new Vector3(0, 0, -0.001f);
            textProvinceRoot.transform.localRotation = Misc.QuaternionZero;
            textProvinceRoot.transform.localScale    = new Vector3(1.0f / mw, 1.0f / mh, 1);

            // Adjusts alpha based on distance to camera
            if (Application.isPlaying)
            {
                FadeProvinceLabels();
            }
        }
Пример #3
0
        void DrawUnityStandardTextLabels()
        {
            ResetDefaultCountryLabelOffset();

            if (meshRects == null)
            {
                meshRects = new List <MeshRect> (_countries.Length);
            }
            else
            {
                meshRects.Clear();
            }
            float mw = mapWidth;
            float mh = mapHeight;

            for (int countryIndex = 0; countryIndex < _countries.Length; countryIndex++)
            {
                Country country = _countries [countryIndex];
                if (country.hidden || !country.labelVisible || country.mainRegionIndex < 0 || country.mainRegionIndex >= country.regions.Count)
                {
                    continue;
                }

                Vector2 center = new Vector2(country.center.x * mapWidth, country.center.y * mh) + country.labelOffset;
                center += GetDefaultCountryLabelOffset(countryIndex);

                Region region = country.regions [country.mainRegionIndex];

                // Adjusts country name length
                string countryName = country.customLabel != null ? country.customLabel : country.name.ToUpper();
                bool   introducedCarriageReturn = false;
                if (countryName.Length > 15)
                {
                    countryName = BreakOneLineString(countryName);
                    introducedCarriageReturn = true;
                }

                // add caption
                GameObject textObj;
                TextMesh   tm;
                Renderer   tmRenderer;
                TextMesh   tmShadow = null;
                if (country.labelTextMeshGO == null)
                {
                    Color labelColor = country.labelColorOverride ? country.labelColor : _countryLabelsColor;
                    Font  customFont = country.labelFontOverride ?? labelsFont;
                    if ((object)customFont == null)
                    {
                        continue;
                    }
                    Material customLabelShadowMaterial = country.labelFontShadowMaterial ?? labelsShadowMaterial;
                    tm      = Drawing.CreateText(countryName, null, center, customFont, labelColor, _showLabelsShadow, customLabelShadowMaterial, _countryLabelsShadowColor, out tmShadow);
                    textObj = tm.gameObject;
                    country.labelTextMesh   = tm;
                    country.labelTextMeshGO = tm.gameObject;
                    tmRenderer = textObj.GetComponent <Renderer> ();
                    Bounds bounds = tmRenderer.bounds;
                    country.labelMeshWidth  = bounds.size.x;
                    country.labelMeshHeight = bounds.size.y;
                    country.labelMeshCenter = center;
                    textObj.transform.SetParent(textRoot.transform, false);
                    textObj.transform.localPosition = center;
                    textObj.layer = textRoot.gameObject.layer;
                    if (_showLabelsShadow)
                    {
                        country.labelShadowTextMesh = tmShadow;                         //textObj.transform.Find ("shadow").GetComponent<TextMesh> ();
                        country.labelShadowTextMesh.gameObject.layer = textObj.layer;
                    }
                }
                else
                {
                    tm      = country.labelTextMesh;
                    textObj = tm.gameObject;
                    textObj.transform.localPosition = center;
                    tmRenderer = textObj.GetComponent <Renderer> ();
                }

                float meshWidth  = country.labelMeshWidth;
                float meshHeight = country.labelMeshHeight;

                // adjusts caption
                Rect  rect = new Rect(region.rect2D.xMin * mw, region.rect2D.yMin * mh, region.rect2D.width * mw, region.rect2D.height * mh);
                float absoluteHeight;
                if (country.labelRotation > 0)
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, country.labelRotation);
                    absoluteHeight = Mathf.Min(rect.height * _countryLabelsSize, rect.width);
                }
                else if (rect.height > rect.width * 1.45f)
                {
                    float angle;
                    if (rect.height > rect.width * 1.5f)
                    {
                        angle = 90;
                    }
                    else
                    {
                        angle = Mathf.Atan2(rect.height, rect.width) * Mathf.Rad2Deg;
                    }
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, angle);
                    absoluteHeight = Mathf.Min(rect.width * _countryLabelsSize, rect.height);
                }
                else
                {
                    absoluteHeight = Mathf.Min(rect.height * _countryLabelsSize, rect.width);
                }

                // adjusts scale to fit width in rect
                float adjustedMeshHeight = introducedCarriageReturn ? meshHeight * 0.5f : meshHeight;
                float scale = absoluteHeight / adjustedMeshHeight;
                if (country.labelFontSizeOverride)
                {
                    scale = country.labelFontSize;
                }
                else
                {
                    float desiredWidth = meshWidth * scale;
                    if (desiredWidth > rect.width)
                    {
                        scale = rect.width / meshWidth;
                    }
                    if (adjustedMeshHeight * scale < _countryLabelsAbsoluteMinimumSize)
                    {
                        scale = _countryLabelsAbsoluteMinimumSize / adjustedMeshHeight;
                    }
                }

                // stretchs out the caption
                float  displayedMeshWidth  = meshWidth * scale;
                float  displayedMeshHeight = meshHeight * scale;
                string wideName;
                int    times = Mathf.FloorToInt(rect.width * 0.45f / (meshWidth * scale));
                if (times > 10)
                {
                    times = 10;
                }
                if (times > 0)
                {
                    StringBuilder sb     = new StringBuilder();
                    string        spaces = new string (' ', times * 2);
                    for (int c = 0; c < countryName.Length; c++)
                    {
                        sb.Append(countryName [c]);
                        if (c < countryName.Length - 1)
                        {
                            sb.Append(spaces);
                        }
                    }
                    wideName = sb.ToString();
                }
                else
                {
                    wideName = countryName;
                }

                if (tm.text.Length != wideName.Length)
                {
                    tm.text             = wideName;
                    displayedMeshWidth  = tmRenderer.bounds.size.x * scale;
                    displayedMeshHeight = tmRenderer.bounds.size.y * scale;
                    if (_showLabelsShadow)
                    {
                        tmShadow.text = wideName;
                    }
                }

                // apply scale
                textObj.transform.localScale = new Vector3(scale, scale, 1);

                // Save mesh rect for overlapping checking
                if (country.labelOffset == Misc.Vector2zero)
                {
                    float    xMin = center.x - displayedMeshWidth * 0.5f;
                    float    yMin = center.y - displayedMeshHeight * 0.5f;
                    float    xMax = xMin + displayedMeshWidth;
                    float    yMax = yMin + displayedMeshHeight;
                    MeshRect mr   = new MeshRect(countryIndex, new Vector4(xMin, yMin, xMax, yMax));
                    meshRects.Add(mr);
                }
            }

            // Simple-fast overlapping checking
            int  cont        = 0;
            bool needsResort = true;

            int meshRectsCount = meshRects.Count;

            while (needsResort && ++cont < 10)
            {
                meshRects.Sort(overlapComparer);
                needsResort = false;
                for (int c = 1; c < meshRectsCount; c++)
                {
                    Vector4 r1 = meshRects [c].rect;
                    for (int prevc = c - 1; prevc >= 0; prevc--)
                    {
                        Vector4 r2       = meshRects [prevc].rect;
                        bool    overlaps = !(r2.x > r1.z || r2.z <r1.x || r2.y> r1.w || r2.w < r1.y);
                        if (overlaps)
                        {
                            needsResort = true;
                            int        thisCountryIndex = meshRects [c].entityIndex;
                            Country    country          = _countries [thisCountryIndex];
                            GameObject thisLabel        = country.labelTextMeshGO;

                            // displaces this label
                            float offsety = r1.w - r2.y;
                            offsety = Mathf.Min(country.regions [country.mainRegionIndex].rect2D.height * mh * 0.35f, offsety);
                            thisLabel.transform.localPosition = new Vector3(country.labelMeshCenter.x, country.labelMeshCenter.y - offsety, thisLabel.transform.localPosition.z);
                            float width  = r1.z - r1.x;
                            float height = r1.w - r1.y;
                            float xMin   = thisLabel.transform.localPosition.x - width * 0.5f;
                            float yMin   = thisLabel.transform.localPosition.y - height * 0.5f;
                            float xMax   = xMin + width;
                            float yMax   = yMin + height;
                            r1 = new Vector4(xMin, yMin, xMax, yMax);
                            meshRects [c].rect = r1;
                        }
                    }
                }
            }
        }