Ejemplo n.º 1
0
        void ComputeBounds()
        {
            Vector2 min = Misc.Vector2max;
            Vector2 max = Misc.Vector2min;

            for (int k = 0; k < points.Length; k++)
            {
                float x = points [k].x;
                float y = points [k].y;
                if (x < min.x)
                {
                    min.x = x;
                }
                if (x > max.x)
                {
                    max.x = x;
                }
                if (y < min.y)
                {
                    min.y = y;
                }
                if (y > max.y)
                {
                    max.y = y;
                }
            }
            rect2D     = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
            rect2DArea = rect2D.width * rect2D.height;
            FastVector.Average(ref min, ref max, ref center);              // center = (min + max) * 0.5f;
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Returns the registered Game Object near a given position
 /// </summary>
 public GameObjectAnimator VGOGet(Vector2 mapPos, float distance)
 {
     distance *= distance;
     CheckVGOsArrayDirty();
     for (int k = 0; k < vgosCount; k++)
     {
         GameObjectAnimator go = vgos[k];
         float d = FastVector.SqrDistanceByValue(go.currentMap2DLocation, mapPos); // Vector2.SqrMagnitude (go.currentMap2DLocation - mapPos);
         if (d <= distance)
         {
             return(go);
         }
     }
     return(null);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Updates the region rect2D. Needed if points is updated manually.
 /// </summary>
 /// <param name="newPoints">New points.</param>
 /// <param name="inflate">If set to <c>true</c> points will be slightly displaced to prevent polygon clipping floating point issues.</param>
 public void UpdatePointsAndRect(Vector2[] newPoints, bool inflate = false)
 {
     sanitized = false;
     points    = newPoints;
     ComputeBounds();
     if (inflate)
     {
         Vector2 tmp = Misc.Vector2zero;
         for (int k = 0; k < points.Length; k++)
         {
             FastVector.NormalizedDirection(ref center, ref points [k], ref tmp);
             FastVector.Add(ref points [k], ref tmp, 0.00001f);
         }
     }
 }
        // Snap positions to country frontiers?
        void SnapToCountryFrontiers(Region region)
        {
            WMSK map            = WMSK.instance;
            int  positionsCount = region.points.Length;

            for (int k = 0; k < positionsCount; k++)
            {
                Vector2 p       = region.points [k];
                float   minDist = float.MaxValue;
                Vector2 nearest = Misc.Vector2zero;
                bool    found   = false;
                for (int c = 0; c < map.countries.Length; c++)
                {
                    Country country = map.countries [c];
                    // if country's bounding box does not contain point, skip it
                    if (!country.regionsRect2D.Contains(p))
                    {
                        continue;
                    }
                    int regionCount = country.regions.Count;
                    for (int cr = 0; cr < regionCount; cr++)
                    {
                        Region countryRegion = country.regions [cr];
                        // if region's bounding box does not contain point, skip it
                        if (!countryRegion.rect2D.Contains(p))
                        {
                            continue;
                        }
                        for (int q = 0; q < countryRegion.points.Length; q++)
                        {
                            float dist = FastVector.SqrDistance(ref countryRegion.points [q], ref p);                              // (countryRegion.points [q] - p).sqrMagnitude;
                            if (dist < minDist)
                            {
                                minDist = dist;
                                nearest = region.points [q];
                                found   = true;
                            }
                        }
                    }
                }
                if (found)
                {
                    region.points [k] = nearest;
                }
            }
            region.RemoveDuplicatePoints();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns the registered Game Object near a given position
        /// </summary>
        public GameObjectAnimator VGOGet(Vector2 mapPos, float distance)
        {
            distance *= distance;
            List <GameObjectAnimator> gos = new List <GameObjectAnimator> (vgos.Values);
            int gosCount = gos.Count;

            for (int k = 0; k < gosCount; k++)
            {
                GameObjectAnimator go = gos [k];
                float d = FastVector.SqrDistanceByValue(go.currentMap2DLocation, mapPos);                  // Vector2.SqrMagnitude (go.currentMap2DLocation - mapPos);
                if (d <= distance)
                {
                    return(go);
                }
            }
            return(null);
        }
Ejemplo n.º 6
0
        public void ScaleMountPoints()
        {
            if (map == null || map.currentCamera == null || map.currentCamera.pixelWidth == 0)
            {
                return;                 // Camera pending setup
            }
            map.GetLocalHitFromScreenPos(Input.mousePosition, out lastPos, false);
            lastPos             = transform.TransformPoint(lastPos);
            lastCamPos          = map.cameraMain.transform.position;
            lastIconSize        = map.cityIconSize;
            lastOrtographicSize = map.currentCamera.orthographicSize;

            Vector3 a = map.currentCamera.WorldToScreenPoint(transform.position);
            Vector3 b = new Vector3(a.x, a.y + MOUNTPOINT_SIZE_ON_SCREEN, a.z);

            if (map.currentCamera.pixelWidth == 0)
            {
                return;                 // Camera pending setup
            }
            Vector3 aa    = map.currentCamera.ScreenToWorldPoint(a);
            Vector3 bb    = map.currentCamera.ScreenToWorldPoint(b);
            float   scale = (aa - bb).magnitude * map.cityIconSize;

            if (map.currentCamera.orthographic)
            {
                scale /= 1 + (map.currentCamera.orthographicSize * map.currentCamera.orthographicSize) * (0.1f / map.transform.localScale.x);
            }
            else
            {
                scale /= 1 + FastVector.SqrDistance(ref lastCamPos, ref lastPos) * (0.1f / map.transform.localScale.x);
            }
            Vector3 newScale = new Vector3(scale / WMSK.mapWidth, scale / WMSK.mapHeight, 1.0f);

            newScale *= 2.0f;
            foreach (Transform t in transform)
            {
                t.localScale = newScale;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns any mount point near the point specified in local coordinates.
        /// </summary>
        /// <param name="separation">Distance threshold (minimum should be MOUNT_POINT_HIT_PRECISION constant).</param>
        public int GetMountPointNearPoint(Vector2 localPoint, float separation)
        {
            if (mountPoints == null)
            {
                return(-1);
            }
            if (separation < MOUNT_POINT_HIT_PRECISION)
            {
                separation = MOUNT_POINT_HIT_PRECISION;
            }
            float separationSqr = separation * separation;
            int   count         = mountPoints.Count;

            for (int c = 0; c < count; c++)
            {
                Vector2 mpLoc   = mountPoints [c].unity2DLocation;
                float   distSqr = FastVector.SqrDistance(ref mpLoc, ref localPoint);                // (mpLoc - localPoint).sqrMagnitude;
                if (distSqr < separationSqr)
                {
                    return(c);
                }
            }
            return(-1);
        }
Ejemplo n.º 8
0
        public void ScaleCities()
        {
            if (map == null || map.currentCamera == null || map.currentCamera.pixelWidth == 0 || gameObject == null)
            {
                return;                 // Camera pending setup
            }
            // annotate current values
            lastPos             = transform.position;
            lastCamPos          = map.currentCamera.transform.position;
            lastIconSize        = map.cityIconSize;
            lastOrtographicSize = map.currentCamera.orthographicSize;

            // get mouse position relative to map in world coordinates
            Vector3 worldPos;

            map.GetLocalHitFromScreenPos(Input.mousePosition, out worldPos, false);
            worldPos = transform.TransformPoint(worldPos);

            // calculates optimal city icon size - deals with WorldToScreenPoint lack of precision
            Vector3 a = map.currentCamera.WorldToScreenPoint(transform.position);

            if (a.z < 0)
            {
                return;
            }
            Vector3 b  = new Vector3(a.x, a.y + CITY_SIZE_ON_SCREEN, a.z);
            Vector3 c  = new Vector3(a.x - CITY_SIZE_ON_SCREEN, a.y, a.z);
            Vector3 aa = map.currentCamera.ScreenToWorldPoint(a);
            Vector3 bb = map.currentCamera.ScreenToWorldPoint(b);
            Vector3 cc = map.currentCamera.ScreenToWorldPoint(c);

            float dist  = ((aa - bb).magnitude + (aa - cc).magnitude) * 0.5f;
            float scale = dist * map.cityIconSize;

            if (map.currentCamera.orthographic)
            {
                scale /= 1.0f + (map.currentCamera.orthographicSize * map.currentCamera.orthographicSize) * (0.1f / map.transform.localScale.x);
            }
            else
            {
                scale /= 1.0f + FastVector.SqrDistance(ref lastCamPos, ref worldPos) * (0.1f / map.transform.localScale.x);
            }
            Vector3 newScale = new Vector3(scale / WMSK.mapWidth, scale / WMSK.mapHeight, 1.0f);

            map.currentCityScale = newScale;

            // check if scale has changed
            Transform tNormalCities = transform.Find("Normal Cities");
            bool      needRescale   = false;
            Transform tChild;

            if (tNormalCities != null && tNormalCities.childCount > 0)
            {
                tChild = tNormalCities.GetChild(0);
                if (tChild != null)
                {
                    if (tChild.localScale != newScale)
                    {
                        needRescale = true;
                    }
                }
            }
            Transform tRegionCapitals = transform.Find("Region Capitals");

            if (!needRescale && tRegionCapitals != null && tRegionCapitals.childCount > 0)
            {
                tChild = tRegionCapitals.GetChild(0);
                if (tChild != null)
                {
                    if (tChild.localScale != newScale)
                    {
                        needRescale = true;
                    }
                }
            }
            Transform tCountryCapitals = transform.Find("Country Capitals");

            if (!needRescale && tCountryCapitals != null && tCountryCapitals.childCount > 0)
            {
                tChild = tCountryCapitals.GetChild(0);
                if (tChild != null)
                {
                    if (tChild.localScale != newScale)
                    {
                        needRescale = true;
                    }
                }
            }

            if (!needRescale)
            {
                return;
            }
            // apply scale to all cities children
            foreach (Transform t in tNormalCities)
            {
                t.localScale = newScale;
            }
            foreach (Transform t in tRegionCapitals)
            {
                t.localScale = newScale * 1.75f;
            }
            foreach (Transform t in tCountryCapitals)
            {
                t.localScale = newScale * 2.0f;
            }
        }
Ejemplo n.º 9
0
        void CheckTiles(TileInfo parent, int currentZoomLevel, int xTile, int yTile, int zoomLevel, int subquadIndex)
        {
            // Is this tile visible?
            TileInfo ti;
            int      tileCode = GetTileHashCode(xTile, yTile, zoomLevel);

            if (!cachedTiles.TryGetValue(tileCode, out ti))
            {
                ti        = new TileInfo(xTile, yTile, zoomLevel, subquadIndex, currentEarthTexture);
                ti.parent = parent;
                if (parent != null)
                {
                    if (parent.children == null)
                    {
                        parent.children = new List <TileInfo> ();
                    }
                    parent.children.Add(ti);
                }
                for (int k = 0; k < 4; k++)
                {
                    Vector2 latlon = Conversion.GetLatLonFromTile(xTile + offsets [k].x, yTile + offsets [k].y, zoomLevel);
                    ti.latlons [k]        = latlon;
                    ti.cornerLocalPos [k] = Conversion.GetLocalPositionFromLatLon(latlon);
                }
                cachedTiles [tileCode] = ti;
            }

            // Check if tile is within restricted area
            if (_tileRestrictToArea)
            {
                if (ti.latlons[0].x <_tileMinMaxLatLon.x || ti.latlons[2].x> _tileMinMaxLatLon.z || ti.latlons[0].y > _tileMinMaxLatLon.w || ti.latlons[2].y < _tileMinMaxLatLon.y)
                {
                    return;
                }
            }

            // Check if any tile corner is visible
            // Phase I
            Vector3 minWorldPos = Misc.Vector3max;
            Vector3 maxWorldPos = Misc.Vector3min;
            Vector3 tmp         = Misc.Vector3zero;

            for (int c = 0; c < 4; c++)
            {
                Vector3 wpos = transform.TransformPoint(ti.cornerLocalPos [c]);
                ti.cornerWorldPos [c] = wpos;
                if (wpos.x < minWorldPos.x)
                {
                    minWorldPos.x = wpos.x;
                }
                if (wpos.y < minWorldPos.y)
                {
                    minWorldPos.y = wpos.y;
                }
                if (wpos.z < minWorldPos.z)
                {
                    minWorldPos.z = wpos.z;
                }
                if (wpos.x > maxWorldPos.x)
                {
                    maxWorldPos.x = wpos.x;
                }
                if (wpos.y > maxWorldPos.y)
                {
                    maxWorldPos.y = wpos.y;
                }
                if (wpos.z > maxWorldPos.z)
                {
                    maxWorldPos.z = wpos.z;
                }
            }

            FastVector.Average(ref minWorldPos, ref maxWorldPos, ref tmp);
            Bounds  bounds       = new Bounds(tmp, maxWorldPos - minWorldPos);
            Vector3 tileMidPoint = bounds.center;


#if DEBUG_TILES
            if (root == null)
            {
                root = new GameObject();
                root.transform.SetParent(transform);
                root.transform.localPosition = Vector3.zero;
                root.transform.localRotation = Misc.QuaternionZero;                 //Quaternion.Euler (0, 0, 0);
            }
#endif

            bool  insideViewport = false;
            float minX = currentCamera.pixelWidth * 2f, minY = currentCamera.pixelHeight * 2f;
            float maxX = -minX, maxY = -minY;
            for (int c = 0; c < 4; c++)
            {
                Vector3 scrPos = currentCamera.WorldToScreenPoint(ti.cornerWorldPos [c]);
                insideViewport = insideViewport || (scrPos.z > 0 && scrPos.x >= 0 && scrPos.x < currentCamera.pixelWidth && scrPos.y >= 0 && scrPos.y < currentCamera.pixelHeight);
                if (scrPos.x < minX)
                {
                    minX = scrPos.x;
                }
                if (scrPos.x > maxX)
                {
                    maxX = scrPos.x;
                }
                if (scrPos.y < minY)
                {
                    minY = scrPos.y;
                }
                if (scrPos.y > maxY)
                {
                    maxY = scrPos.y;
                }
            }
            if (!insideViewport)
            {
                insideViewport = GeometryUtility.TestPlanesAABB(cameraPlanes, bounds);
                if (!insideViewport && _wrapHorizontally && _wrapCamera.enabled)
                {
                    insideViewport = GeometryUtility.TestPlanesAABB(wrapCameraPlanes, bounds);
                }
            }

            ti.insideViewport = insideViewport;
            ti.visible        = false;
            if (insideViewport)
            {
                if (!ti.created)
                {
                    CreateTile(ti);
                }

                if (!ti.gameObject.activeSelf)
                {
                    ti.gameObject.SetActive(true);
                }

                // Manage hierarchy of tiles
                float aparentSize = maxY - minY;
                bool  tileIsBig   = aparentSize > currentTileSize;

                                #if DEBUG_TILES
                if (ti.gameObject != null)
                {
                    ti.gameObject.GetComponent <TileInfoEx> ().bigTile   = tileIsBig;
                    ti.gameObject.GetComponent <TileInfoEx> ().zoomLevel = ti.zoomLevel;
                }
                                #endif

                if ((tileIsBig || zoomLevel < TILE_MIN_ZOOM_LEVEL) && zoomLevel < _tileMaxZoomLevel)
                {
                    // Load nested tiles
                    CheckTiles(ti, currentZoomLevel, xTile * 2, yTile * 2, zoomLevel + 1, 0);
                    CheckTiles(ti, currentZoomLevel, xTile * 2 + 1, yTile * 2, zoomLevel + 1, 1);
                    CheckTiles(ti, currentZoomLevel, xTile * 2, yTile * 2 + 1, zoomLevel + 1, 2);
                    CheckTiles(ti, currentZoomLevel, xTile * 2 + 1, yTile * 2 + 1, zoomLevel + 1, 3);
                    ti.renderer.enabled = false;
                }
                else
                {
                    ti.visible = true;

                    // Show tile renderer
                    if (!ti.renderer.enabled)
                    {
                        ti.renderer.enabled = true;
                    }

                    // If parent tile is loaded then use that as placeholder texture
                    if (ti.zoomLevel > TILE_MIN_ZOOM_LEVEL && ti.parent.loadStatus == TILE_LOAD_STATUS.Loaded && !ti.placeholderImageSet)
                    {
                        ti.placeholderImageSet = true;
                        ti.parentTextureCoords = placeHolderUV [ti.subquadIndex];
                        ti.SetPlaceholderImage(ti.parent.texture);
                    }

                    if (ti.loadStatus == TILE_LOAD_STATUS.Loaded)
                    {
                        if (!ti.hasAnimated)
                        {
                            ti.hasAnimated = true;
                            ti.Animate(1f, AnimationEnded);
                        }
                    }
                    else if (ti.loadStatus == TILE_LOAD_STATUS.Inactive)
                    {
                        ti.distToCamera = FastVector.SqrDistance(ref ti.cornerWorldPos [0], ref currentCameraPosition) * ti.zoomLevel;
                        ti.loadStatus   = TILE_LOAD_STATUS.InQueue;
                        ti.queueTime    = Time.time;
                        loadQueue.Add(ti);
                    }
                    if (ti.children != null)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            TileInfo tiChild = ti.children [k];
                            HideTile(tiChild);
                        }
                    }
                }
            }
            else
            {
                HideTile(ti);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Used internally by the Map Editor. It will recalculate de boundaries and optimize frontiers based on new data of provinces array
        /// </summary>
        public void RefreshProvinceGeometry(IAdminEntity province)
        {
            lastProvinceLookupCount = -1;
            float maxVol = 0;

            if (province.regions == null)
            {
                ReadProvincePackedString(province);
            }
            if (province.regions == null)
            {
                return;
            }
            int     regionCount = province.regions.Count;
            Vector2 minProvince = Misc.Vector2one * 10;
            Vector2 maxProvince = -minProvince;
            Vector2 min         = Misc.Vector2one * 10f;
            Vector2 max         = -min;

            for (int r = 0; r < regionCount; r++)
            {
                Region provinceRegion = province.regions [r];
                provinceRegion.entity      = province;                  // just in case one country has been deleted
                provinceRegion.regionIndex = r;                         // just in case a region has been deleted
                int coorCount = provinceRegion.points.Length;
                min.x = min.y = 10f;
                max.x = max.y = -10f;
                for (int c = 0; c < coorCount; c++)
                {
                    float x = provinceRegion.points [c].x;
                    float y = provinceRegion.points [c].y;
                    if (x < min.x)
                    {
                        min.x = x;
                    }
                    if (x > max.x)
                    {
                        max.x = x;
                    }
                    if (y < min.y)
                    {
                        min.y = y;
                    }
                    if (y > max.y)
                    {
                        max.y = y;
                    }
                }
                FastVector.Average(ref min, ref max, ref provinceRegion.center);

                if (min.x < minProvince.x)
                {
                    minProvince.x = min.x;
                }
                if (min.y < minProvince.y)
                {
                    minProvince.y = min.y;
                }
                if (max.x > maxProvince.x)
                {
                    maxProvince.x = max.x;
                }
                if (max.y > maxProvince.y)
                {
                    maxProvince.y = max.y;
                }
                provinceRegion.rect2D     = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
                provinceRegion.rect2DArea = provinceRegion.rect2D.width * provinceRegion.rect2D.height;
                float vol = FastVector.SqrDistance(ref max, ref min);                  // (max - min).sqrMagnitude;
                if (vol > maxVol)
                {
                    maxVol = vol;
                    province.mainRegionIndex = r;
                    province.center          = provinceRegion.center;
                }
            }
            province.regionsRect2D = new Rect(minProvince.x, minProvince.y, Math.Abs(maxProvince.x - minProvince.x), Mathf.Abs(maxProvince.y - minProvince.y));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Unpacks province geodata information. Used by Map Editor.
        /// </summary>
        /// <param name="province">Province.</param>
        public void ReadProvincePackedString(IAdminEntity entity)
        {
            Province province = (Province)entity;

            if (province == null || province.packedRegions == null)
            {
                return;
            }
            string[] regions     = province.packedRegions.Split(SPLIT_SEP_ASTERISK, StringSplitOptions.RemoveEmptyEntries);
            int      regionCount = regions.Length;

            province.regions = new List <Region> (regionCount);
            float   maxVol      = float.MinValue;
            Vector2 minProvince = Misc.Vector2one * 10;
            Vector2 maxProvince = -minProvince;

            for (int r = 0; r < regionCount; r++)
            {
                string[] coordinates    = regions [r].Split(SPLIT_SEP_SEMICOLON, StringSplitOptions.RemoveEmptyEntries);
                int      coorCount      = coordinates.Length;
                Vector2  min            = Misc.Vector2one * 10;
                Vector2  max            = -min;
                Region   provinceRegion = new Region(province, province.regions.Count);
                provinceRegion.points = new Vector2[coorCount];
                for (int c = 0; c < coorCount; c++)
                {
                    float x, y;
                    GetPointFromPackedString(ref coordinates [c], out x, out y);
                    if (x < min.x)
                    {
                        min.x = x;
                    }
                    if (x > max.x)
                    {
                        max.x = x;
                    }
                    if (y < min.y)
                    {
                        min.y = y;
                    }
                    if (y > max.y)
                    {
                        max.y = y;
                    }
                    provinceRegion.points [c].x = x;
                    provinceRegion.points [c].y = y;
                }
                FastVector.Average(ref min, ref max, ref provinceRegion.center);
                provinceRegion.sanitized = true;
                province.regions.Add(provinceRegion);

                // Calculate province bounding rect
                if (min.x < minProvince.x)
                {
                    minProvince.x = min.x;
                }
                if (min.y < minProvince.y)
                {
                    minProvince.y = min.y;
                }
                if (max.x > maxProvince.x)
                {
                    maxProvince.x = max.x;
                }
                if (max.y > maxProvince.y)
                {
                    maxProvince.y = max.y;
                }
                provinceRegion.rect2D     = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
                provinceRegion.rect2DArea = provinceRegion.rect2D.width * provinceRegion.rect2D.height;
                float vol = FastVector.SqrDistance(ref min, ref max);                  // (max - min).sqrMagnitude;
                if (vol > maxVol)
                {
                    maxVol = vol;
                    province.mainRegionIndex = r;
                    province.center          = provinceRegion.center;
                }
            }
            province.regionsRect2D = new Rect(minProvince.x, minProvince.y, Math.Abs(maxProvince.x - minProvince.x), Mathf.Abs(maxProvince.y - minProvince.y));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Returns an optimal route from startPosition to endPosition with options.
        /// </summary>
        /// <returns>The route.</returns>
        /// <param name="startPosition">Start position in map coordinates (-0.5...0.5)</param>
        /// <param name="endPosition">End position in map coordinates (-0.5...0.5)</param>
        /// <param name="totalCost">The total cost of traversing the path</param>
        /// <param name="terrainCapability">Type of terrain that the unit can pass through</param>
        /// <param name="minAltitude">Minimum altitude (0..1)</param>
        /// <param name="maxAltitude">Maximum altutude (0..1)</param>
        /// <param name="maxSearchCost">Maximum search cost for the path finding algorithm. A value of -1 will use the global default defined by pathFindingMaxCost</param>
        public List <Vector2> FindRoute(Vector2 startPosition, Vector2 endPosition, out int totalCost, TERRAIN_CAPABILITY terrainCapability = TERRAIN_CAPABILITY.Any, float minAltitude = 0, float maxAltitude = 1f, int maxSearchCost = -1, int maxSearchSteps = -1)
        {
            ComputeRouteMatrix(terrainCapability, minAltitude, maxAltitude);
            totalCost = 0;
            Point startingPoint = new Point((int)((startPosition.x + 0.5f) * EARTH_ROUTE_SPACE_WIDTH),
                                            (int)((startPosition.y + 0.5f) * EARTH_ROUTE_SPACE_HEIGHT));
            Point endingPoint = new Point((int)((endPosition.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                          (int)((endPosition.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));

            endingPoint.X = Mathf.Clamp(endingPoint.X, 0, EARTH_ROUTE_SPACE_WIDTH - 1);
            endingPoint.Y = Mathf.Clamp(endingPoint.Y, 0, EARTH_ROUTE_SPACE_HEIGHT - 1);

            // Helper to find a minimum path in case the destination position is on a different terrain type
            if (terrainCapability == TERRAIN_CAPABILITY.OnlyWater)
            {
                int arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                if ((earthRouteMatrix [arrayIndex] & 4) == 0)
                {
                    int regionIndex  = -1;
                    int countryIndex = GetCountryIndex(endPosition, out regionIndex);
                    if (countryIndex >= 0 && regionIndex >= 0)
                    {
                        List <Vector2> coastPositions      = GetCountryCoastalPoints(countryIndex, regionIndex, 0.001f);
                        float          minDist             = float.MaxValue;
                        Vector2        bestPosition        = Misc.Vector2zero;
                        int            coastPositionsCount = coastPositions.Count;
                        // Get nearest position to the ship which is on water
                        for (int k = 0; k < coastPositionsCount; k++)
                        {
                            Vector2 waterPosition;
                            if (ContainsWater(coastPositions [k], 0.001f, out waterPosition))
                            {
                                float dist = FastVector.SqrDistance(ref endPosition, ref waterPosition);                                  // (endPosition - waterPosition).sqrMagnitude;
                                if (dist < minDist)
                                {
                                    minDist      = dist;
                                    bestPosition = waterPosition;
                                }
                            }
                        }
                        if (minDist < float.MaxValue)
                        {
                            endPosition = bestPosition;
                        }
                        endingPoint = new Point((int)((endPosition.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                                (int)((endPosition.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));
                        arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                        if ((earthRouteMatrix [arrayIndex] & 4) == 0)
                        {
                            Vector2 direction = Misc.Vector2zero;
                            for (int k = 1; k <= 10; k++)
                            {
                                if (k == 10 || startPosition == endPosition)
                                {
                                    return(null);
                                }
                                FastVector.NormalizedDirection(ref endPosition, ref startPosition, ref direction);
                                Vector2 p = endPosition + direction * (float)k / EARTH_ROUTE_SPACE_WIDTH;
                                endingPoint = new Point((int)((p.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                                        (int)((p.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));
                                arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                                if ((earthRouteMatrix [arrayIndex] & 4) > 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            List <Vector2> routePoints = null;

            // Minimum distance for routing?
            if (Mathf.Abs(endingPoint.X - startingPoint.X) > 0 || Mathf.Abs(endingPoint.Y - startingPoint.Y) > 0)
            {
                finder.Formula       = _pathFindingHeuristicFormula;
                finder.MaxSearchCost = maxSearchCost < 0 ? _pathFindingMaxCost : maxSearchCost;
                finder.MaxSteps      = maxSearchSteps < 0 ? _pathFindingMaxSteps : maxSearchSteps;
                if (_pathFindingEnableCustomRouteMatrix)
                {
                    finder.OnCellCross = FindRoutePositionValidator;
                }
                else
                {
                    finder.OnCellCross = null;
                }
                List <PathFinderNode> route = finder.FindPath(startingPoint, endingPoint, out totalCost);
                if (route != null)
                {
                    routePoints = new List <Vector2> (route.Count);
                    routePoints.Add(startPosition);
                    for (int r = route.Count - 1; r >= 0; r--)
                    {
                        float   x       = (float)route [r].X / EARTH_ROUTE_SPACE_WIDTH - 0.5f;
                        float   y       = (float)route [r].Y / EARTH_ROUTE_SPACE_HEIGHT - 0.5f;
                        Vector2 stepPos = new Vector2(x, y);

                        // due to grid effect the first step may be farther than the current position, so we skip it in that case.
                        if (r == route.Count - 1 && (endPosition - startPosition).sqrMagnitude < (endPosition - stepPos).sqrMagnitude)
                        {
                            continue;
                        }

                        routePoints.Add(stepPos);
                    }
                }
                else
                {
                    return(null);                       // no route available
                }
            }

            // Add final step if it's appropiate
            bool hasWater = ContainsWater(endPosition);

            if (terrainCapability == TERRAIN_CAPABILITY.Any ||
                (terrainCapability == TERRAIN_CAPABILITY.OnlyWater && hasWater) ||
                (terrainCapability == TERRAIN_CAPABILITY.OnlyGround && !hasWater))
            {
                if (routePoints == null)
                {
                    routePoints = new List <Vector2> ();
                    routePoints.Add(startPosition);
                    routePoints.Add(endPosition);
                }
                else
                {
                    routePoints [routePoints.Count - 1] = endPosition;
                }
            }

            // Check that ground units ends in a position where GetCountryIndex returns a valid index
            if (terrainCapability == TERRAIN_CAPABILITY.OnlyGround)
            {
                int     rr = routePoints.Count - 1;
                Vector2 dd = routePoints [rr - 1] - routePoints [rr];
                dd *= 0.1f;
                while (GetCountryIndex(routePoints [rr]) < 0)
                {
                    routePoints [rr] += dd;
                }
            }

            return(routePoints);
        }
Ejemplo n.º 13
0
        void DrawTextMeshProLabels()
        {
            if (labelsFontTMPro == null)
            {
                return;
            }

            float mw = mapWidth;
            float mh = mapHeight;

            Vector2 center = Misc.Vector2zero;

            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;
                }

                Region          region = country.regions[country.mainRegionIndex];
                CurvedLabelInfo curvedLabel;
                if (!ComputeCurvedLabelData(region, out curvedLabel))
                {
                    continue;
                }

                if (country.labelOffset.x != 0 || country.labelOffset.y != 0)
                {
                    center = country.center + country.labelOffset;
                }
                else
                {
                    FastVector.Average(ref curvedLabel.axisStart, ref curvedLabel.axisEnd, ref center);                     // (curvedLabel.axisStart + curvedLabel.axisEnd) * 0.5f;
                }
                center.x *= mw;
                center.y *= mh;

                // Adjusts country name length
                string countryName = country.customLabel != null ? country.customLabel : country.name.ToUpper();
                if (countryName.Length == 0)
                {
                    continue;
                }

                if (countryName.Length > 15)
                {
                    countryName = BreakOneLineString(countryName);
                }

                // add caption
                GameObject  textObj;
                TextMeshPro tm;
                Color       labelColor = country.labelColorOverride ? country.labelColor : _countryLabelsColor;
                if (country.labelTextMeshGO == null)
                {
                    // create base text
                    textObj            = new GameObject(countryName);
                    textObj.hideFlags  = HideFlags.DontSave;
                    textObj.hideFlags |= HideFlags.HideInHierarchy;
                    tm                       = textObj.AddComponent <TextMeshPro>();
                    tm.alignment             = TextAlignmentOptions.Center;
                    tm.enableWordWrapping    = false;
                    country.labelTextMeshPro = tm;
                    country.labelTextMeshGO  = tm.gameObject;
                    textObj.transform.SetParent(textRoot.transform, false);
                    textObj.layer = textRoot.gameObject.layer;
                }
                else
                {
                    tm      = (TextMeshPro)country.labelTextMeshPro;
                    textObj = tm.gameObject;
                    textObj.transform.localPosition = center;
                }
                tm.font  = (TMP_FontAsset)labelsFontTMPro;
                tm.color = labelColor;
                if (_countryLabelsEnableAutomaticFade)
                {
                    // By using fontMaterial we're forcing to instantiate the material which will enable individual colors and alpha
                    Material mat = tm.fontMaterial;
                    mat.SetColor("_OutlineColor", _countryLabelsOutlineColor);
                    mat.SetFloat("_OutlineWidth", _countryLabelsOutlineWidth);
                    mat.hideFlags = HideFlags.DontSave;
                }
                else
                {
                    tm.fontSharedMaterial.SetColor("_OutlineColor", _countryLabelsOutlineColor);
                    tm.fontSharedMaterial.SetFloat("_OutlineWidth", _countryLabelsOutlineWidth);
                }
                tm.text = countryName;
                textObj.transform.localPosition = center;
                country.labelMeshWidth          = tm.preferredWidth;
                country.labelMeshHeight         = tm.preferredHeight;
                country.labelMeshCenter         = center;

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

                // adjusts scale to fit in region
                Vector2 axis = curvedLabel.axisEnd - curvedLabel.axisStart;
                float   scale;
                if (country.labelFontSizeOverride)
                {
                    scale = country.labelFontSize;
                }
                else
                {
                    // axisWidth represents the length of the label along the longest axis
                    float axisWidth = new Vector2(axis.x * mw, axis.y * mh).magnitude;
                    // axisAveragedWidth represents the average length of the region (used as a maximum height for the label)
                    float axisAveragedThickness = new Vector2(curvedLabel.axisAveragedThickness.x * mw, curvedLabel.axisAveragedThickness.y * mh).magnitude;
                    float scaleheight           = axisAveragedThickness / meshHeight;
                    float scaleWidth            = axisWidth / meshWidth;
                    scale = Mathf.Min(scaleWidth, scaleheight);
                    if (meshHeight * scale < _countryLabelsAbsoluteMinimumSize)
                    {
                        scale = _countryLabelsAbsoluteMinimumSize / meshHeight;
                    }
                    scale *= _countryLabelsSize * 2f;
                }

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

                // Apply axis rotation or user defined rotation
                if (country.labelRotation > 0)
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, country.labelRotation);
                }
                else
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, curvedLabel.axisAngle);
                }

                if (_countryLabelsCurvature > 0)
                {
                    // Compute fitting curve

                    if (labelsCurve == null || labelsCurve.length == 0)
                    {
                        ComputeLabelsCurve();
                    }

                    tm.havePropertiesChanged = true;          // Need to force the TextMeshPro Object to be updated.
                    tm.ForceMeshUpdate();                     // Generate the mesh and populate the textInfo with data we can use and manipulate.

                    TMP_TextInfo textInfo       = tm.textInfo;
                    int          characterCount = textInfo.characterCount;

                    float boundsMinX = tm.bounds.min.x;
                    float boundsMaxX = tm.bounds.max.x;
                    // map bounds to axis length
                    float axisLengthWS = new Vector2(axis.x * mw / scale, axis.y * mh / scale).magnitude;
                    float boundsLength = boundsMaxX - boundsMinX;
                    float boundsMid    = (boundsMaxX + boundsMinX) * 0.5f;
                    boundsMinX = boundsMid - (boundsMid - boundsMinX) * axisLengthWS / boundsLength;
                    boundsMaxX = boundsMid + (boundsMaxX - boundsMid) * axisLengthWS / boundsLength;

                    float curveMultiplier = new Vector2(curvedLabel.axisMidDisplacement.x * mw / scale, curvedLabel.axisMidDisplacement.y * mh / scale).magnitude *_countryLabelsCurvature;
                    // check if axisAveragedThickness is above or below axis
                    Vector2 a   = axis * 0.5f + curvedLabel.axisMidDisplacement;
                    float   dot = a.x * -axis.y + a.y * axis.x;
                    if (dot < 0)
                    {
                        curveMultiplier *= -1f;
                    }
                    float boundsWidth = boundsMaxX - boundsMinX;

                    // Get the index of the mesh used by this character.
                    int       materialIndex = textInfo.characterInfo[0].materialReferenceIndex;
                    Vector3[] vertices      = textInfo.meshInfo[materialIndex].vertices;

                    for (int i = 0; i < characterCount; i++)
                    {
                        if (!textInfo.characterInfo[i].isVisible)
                        {
                            continue;
                        }

                        int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                        // Compute the baseline mid point for each character
                        Vector2 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);

                        // Apply offset to adjust our pivot point.
                        vertices[vertexIndex + 0].x -= offsetToMidBaseline.x;
                        vertices[vertexIndex + 0].y -= offsetToMidBaseline.y;
                        vertices[vertexIndex + 1].x -= offsetToMidBaseline.x;
                        vertices[vertexIndex + 1].y -= offsetToMidBaseline.y;
                        vertices[vertexIndex + 2].x -= offsetToMidBaseline.x;
                        vertices[vertexIndex + 2].y -= offsetToMidBaseline.y;
                        vertices[vertexIndex + 3].x -= offsetToMidBaseline.x;
                        vertices[vertexIndex + 3].y -= offsetToMidBaseline.y;

                        // Compute the angle of rotation for each character based on the animation curve
                        float x0 = (offsetToMidBaseline.x - boundsMinX) / boundsWidth;                         // Character's position relative to the bounds of the mesh.
                        float x1 = x0 + 0.01f;
                        float y0 = labelsCurve.Evaluate(x0) * curveMultiplier;
                        float y1 = labelsCurve.Evaluate(x1) * curveMultiplier;

                        Vector2 tangent = new Vector2(x1 * boundsWidth + boundsMinX - offsetToMidBaseline.x, y1 - y0);                         // - new Vector3 (offsetToMidBaseline.x, y0);
                        dot = Mathf.Acos(tangent.normalized.x) * Mathf.Rad2Deg;
                        float angle = tangent.y > 0 ? dot : 360 - dot;

                        Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(offsetToMidBaseline.x, y0 + offsetToMidBaseline.y, 0), Quaternion.Euler(0, 0, angle), Misc.Vector3one);

                        vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
                        vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
                        vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
                        vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);

//																								vertices [vertexIndex + 0] += offsetToMidBaseline;
//																								vertices [vertexIndex + 1] += offsetToMidBaseline;
//																								vertices [vertexIndex + 2] += offsetToMidBaseline;
//																								vertices [vertexIndex + 3] += offsetToMidBaseline;
                    }

                    // Upload the mesh with the revised information
                    tm.UpdateVertexData();
                }
                country.labelMeshWidth  = tm.bounds.size.x;
                country.labelMeshHeight = tm.bounds.size.y;

//																GameObject sphere3 = GameObject.CreatePrimitive (PrimitiveType.Sphere);
//																sphere3.name = "Axis Middle";
//																sphere3.transform.SetParent (o.transform, true);
//																sphere3.transform.localPosition = (curvedLabel.axisStart + curvedLabel.axisEnd) * 0.5f;
//																sphere3.transform.localScale *= 0.3f;
//
//																GameObject sphere4 = GameObject.CreatePrimitive (PrimitiveType.Sphere);
//																sphere4.name = "avgAxisPoint";
//																sphere4.transform.SetParent (o.transform, true);
//																sphere4.transform.localPosition = (curvedLabel.axisStart + curvedLabel.axisEnd) * 0.5f + curvedLabel.axisMidDisplacement;
//																sphere4.GetComponent<Renderer> ().material.color = Color.red;
//																sphere4.transform.localScale *= 0.2f;

                StartCoroutine(RepositionTexts());
            }
        }
Ejemplo n.º 14
0
        void UpdateArrowCap(ref GameObject placeholder, ref GameObject obj, GameObject cap, bool flipDirection, Vector3 arrowBasePos, Vector3 arrowTipPos, Vector3 scale, float offset, Material capMaterial)
        {
            if (obj == null)
            {
                placeholder = new GameObject("CapPlaceholder");
                placeholder.transform.SetParent(transform, false);
                if (!usesViewport)
                {
                    placeholder.transform.localScale = new Vector3(1f / transform.lossyScale.x, 1f / transform.lossyScale.y, 1f);
                }
                obj = Instantiate <GameObject>(cap);
                capSpriteRenderer = obj.GetComponent <SpriteRenderer>();
                if (capSpriteRenderer != null)
                {
                    capSpriteRenderer.color = lineMaterial.color;
                    capStartColor           = capSpriteRenderer.color;
                }
                capMeshRenderer = obj.GetComponent <MeshRenderer>();
                if (capMeshRenderer != null)
                {
                    capMeshRenderer.sharedMaterial = capMaterial != null ? capMaterial : lineMaterial;
                    capStartColor = capMeshRenderer.sharedMaterial.color;
                }
                obj.transform.SetParent(placeholder.transform);
                obj.SetActive(false);
            }

            // set position
            Vector3 pos = Misc.Vector3zero;

            if (!usesViewport)
            {
                arrowBasePos = map.transform.TransformPoint(arrowBasePos);
                arrowTipPos  = map.transform.TransformPoint(arrowTipPos);
            }

            // Length of cap based on size
            if (arrowBasePos != arrowTipPos)
            {
                Vector3 dir = Misc.Vector3zero;
                FastVector.NormalizedDirection(ref arrowBasePos, ref arrowTipPos, ref dir);
                pos = arrowTipPos - dir * offset;
                if (!obj.activeSelf)
                {
                    obj.SetActive(true);
                }
                obj.transform.position = pos;

                // look to camera
                if (usesViewport)
                {
                    Vector3 camDir = pos - map.cameraMain.transform.position;
                    obj.transform.LookAt(arrowTipPos + dir * 100f, camDir);
                }
                else
                {
                    Vector3 prdir = Vector3.ProjectOnPlane(dir, map.transform.forward);
                    obj.transform.LookAt(pos + map.transform.forward, prdir);
                    obj.transform.Rotate(obj.transform.forward, 90, Space.Self);
                }

                if (flipDirection)
                {
                    obj.transform.Rotate(180, 0, 0, Space.Self);
                }
            }
            obj.transform.localScale = scale;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Used internally by the Map Editor. It will recalculate de boundaries and optimize frontiers based on new data of countries array
        /// </summary>
        public void RefreshCountryGeometry(IAdminEntity country)
        {
            float maxVol = 0;

            if (country.regions == null)
            {
                return;
            }
            int     regionCount = country.regions.Count;
            Vector2 min         = Misc.Vector2one * 10;
            Vector2 max         = -min;
            Vector2 minCountry  = Misc.Vector2one * 10;
            Vector2 maxCountry  = -minCountry;

            for (int r = 0; r < regionCount; r++)
            {
                Region countryRegion = country.regions [r];
                if (countryRegion.points == null)
                {
                    continue;
                }
                countryRegion.entity      = country;            // just in case one country has been deleted
                countryRegion.regionIndex = r;                  // just in case a region has been deleted
                int coorCount = countryRegion.points.Length;
                min.x = min.y = 10f;
                max.x = max.y = -10;
                for (int c = 0; c < coorCount; c++)
                {
                    float x = countryRegion.points [c].x;
                    float y = countryRegion.points [c].y;
                    if (x < min.x)
                    {
                        min.x = x;
                    }
                    if (x > max.x)
                    {
                        max.x = x;
                    }
                    if (y < min.y)
                    {
                        min.y = y;
                    }
                    if (y > max.y)
                    {
                        max.y = y;
                    }
                }
                FastVector.Average(ref min, ref max, ref countryRegion.center);                  // countryRegion.center = (min + max) * 0.5f;

                // Calculate country bounding rect
                if (min.x < minCountry.x)
                {
                    minCountry.x = min.x;
                }
                if (min.y < minCountry.y)
                {
                    minCountry.y = min.y;
                }
                if (max.x > maxCountry.x)
                {
                    maxCountry.x = max.x;
                }
                if (max.y > maxCountry.y)
                {
                    maxCountry.y = max.y;
                }
                // Calculate bounding rect
                countryRegion.rect2D     = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
                countryRegion.rect2DArea = countryRegion.rect2D.width * countryRegion.rect2D.height;
                float vol = FastVector.SqrDistance(ref max, ref min);                  // (max - min).sqrMagnitude;
                if (vol > maxVol)
                {
                    maxVol = vol;
                    country.mainRegionIndex = r;
                    country.center          = countryRegion.center;
                }
            }
            country.regionsRect2D = new Rect(minCountry.x, minCountry.y, Math.Abs(maxCountry.x - minCountry.x), Mathf.Abs(maxCountry.y - minCountry.y));
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Returns true if the unit is near given map coordinate (optionally pass a max distance value).
 /// </summary>
 /// <returns><c>true</c> if this instance is near the specified mapPosition maxDistance; otherwise, <c>false</c>.</returns>
 /// <param name="mapPosition">Map position.</param>
 /// <param name="maxDistance">Max distance.</param>
 public bool isNear(Vector2 mapPosition, float maxDistance = 0.01f)
 {
     return(FastVector.SqrDistance(ref _currentMap2DLocation, ref mapPosition) < maxDistance * maxDistance);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Calculates correct province for cities
        /// </summary>
        public void FixOrphanCities()
        {
            if (_map.provinces == null)
            {
                return;
            }

            for (int c = 0; c < _map.cities.Length; c++)
            {
                City city = _map.cities[c];
                if (city.countryIndex == -1)
                {
                    for (int k = 0; k < _map.countries.Length; k++)
                    {
                        Country co = _map.countries[k];
                        for (int kr = 0; kr < co.regions.Count; kr++)
                        {
                            if (co.regions[kr].Contains(city.unity2DLocation))
                            {
                                city.countryIndex = k;
                                cityChanges       = true;
                                k = 100000;
                                break;
                            }
                        }
                    }
                }
                if (city.countryIndex == -1)
                {
                    float minDist = float.MaxValue;
                    for (int k = 0; k < _map.countries.Length; k++)
                    {
                        Country co = _map.countries[k];
                        for (int kr = 0; kr < co.regions.Count; kr++)
                        {
                            float dist = FastVector.SqrDistance(ref co.regions[kr].center, ref city.unity2DLocation);
                            if (dist < minDist)
                            {
                                minDist           = dist;
                                city.countryIndex = k;
                                cityChanges       = true;
                            }
                        }
                    }
                }

                if (city.province.Length == 0)
                {
                    Country country = _map.countries[city.countryIndex];
                    if (country.provinces == null)
                    {
                        continue;
                    }
                    for (int p = 0; p < country.provinces.Length; p++)
                    {
                        Province province = country.provinces[p];
                        if (province.regions == null)
                        {
                            _map.ReadProvincePackedString(province);
                        }
                        for (int pr = 0; pr < province.regions.Count; pr++)
                        {
                            Region reg = province.regions[pr];
                            if (reg.Contains(city.unity2DLocation))
                            {
                                city.province = province.name;
                                cityChanges   = true;
                                p             = 100000;
                                break;
                            }
                        }
                    }
                }
            }

            for (int c = 0; c < _map.cities.Length; c++)
            {
                City city = _map.cities[c];
                if (city.province.Length == 0)
                {
                    float minDist = float.MaxValue;
                    int   pg      = -1;
                    for (int p = 0; p < _map.provinces.Length; p++)
                    {
                        Province province = _map.provinces[p];
                        if (province.regions == null)
                        {
                            _map.ReadProvincePackedString(province);
                        }
                        for (int pr = 0; pr < province.regions.Count; pr++)
                        {
                            Region pregion = province.regions[pr];
                            for (int prp = 0; prp < pregion.points.Length; prp++)
                            {
                                float dist = FastVector.SqrDistance(ref city.unity2DLocation, ref pregion.points[prp]);
                                if (dist < minDist)
                                {
                                    minDist = dist;
                                    pg      = p;
                                }
                            }
                        }
                    }
                    if (pg >= 0)
                    {
                        city.province = _map.provinces[pg].name;
                        cityChanges   = true;
                    }
                }
            }
        }
Ejemplo n.º 18
0
        public static void UpdateDashedLine(MeshFilter meshFilter, List <Vector3> points, float thickness, bool worldSpace, ref Vector3[] meshPoints, ref int[] triPoints, ref Vector2[] uv)
        {
            int max = (points.Count / 2) * 2;

            if (max == 0)
            {
                return;
            }

            int numPoints = 8 * 3 * max / 2;

            if (numPoints > 65000)
            {
                return;
            }

            Mesh mesh         = meshFilter.sharedMesh;
            bool reassignMesh = false;

            if (mesh == null || meshPoints == null || mesh.vertexCount != numPoints)
            {
                meshPoints   = new Vector3[numPoints];
                triPoints    = new int[numPoints];
                uv           = new Vector2[numPoints];
                reassignMesh = true;
            }

            int mp = 0;

            thickness *= 0.5f;
            float   y0     = 0f;          //Mathf.Sin (0.0f * Mathf.Deg2Rad);
            float   x0     = 1f;          //Mathf.Cos (0.0f * Mathf.Deg2Rad);
            float   y1     = 0.8660254f;  //Mathf.Sin (120.0f * Mathf.Deg2Rad);
            float   x1     = -0.5f;       //Mathf.Cos (120.0f * Mathf.Deg2Rad);
            float   y2     = -0.8660254f; //Mathf.Sin (240.0f * Mathf.Deg2Rad);
            float   x2     = -0.5f;       //Mathf.Cos (240.0f * Mathf.Deg2Rad);
            Vector3 up     = WMSK.instance.currentCamera.transform.forward;
            Vector3 axis   = Misc.Vector3zero;
            float   scaleX = worldSpace ? 1f : 0.5f;

            Vector3 tmp = Misc.Vector3zero;

            for (int p = 0; p < max; p += 2)
            {
                Vector3 p0 = points [p];
                Vector3 p1 = points [p + 1];

                FastVector.NormalizedDirection(ref p0, ref p1, ref tmp);

                // Front triangle
                Vector3 right = Vector3.Cross(up, tmp);

//				Vector3 axis = (up * y0 + right * x0).normalized;
                FastVector.CombineAndNormalize(ref up, y0, ref right, x0, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 0] = p0 + axis * thickness;

//				axis = (up * y2 + right * x2).normalized;
                FastVector.CombineAndNormalize(ref up, y2, ref right, x2, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 1] = p0 + axis * thickness;

//				axis = (up * y1 + right * x1).normalized;
                FastVector.CombineAndNormalize(ref up, y1, ref right, x1, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 2] = p0 + axis * thickness;

                triPoints [mp + 0] = mp + 0;
                triPoints [mp + 1] = mp + 1;
                triPoints [mp + 2] = mp + 2;
                uv [mp + 0]        = Misc.Vector2zero;
                uv [mp + 1]        = Misc.Vector2right;
                uv [mp + 2]        = Misc.Vector2up;

                // Back triangle
//				axis =  (up * y0 + right * x0).normalized;
                FastVector.CombineAndNormalize(ref up, y0, ref right, x0, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 3] = p1 + axis * thickness;

//				axis = (up * y1 + right * x1).normalized;
                FastVector.CombineAndNormalize(ref up, y1, ref right, x1, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 4] = p1 + axis * thickness;

//				axis = (up * y2 + right * x2).normalized;
                FastVector.CombineAndNormalize(ref up, y2, ref right, x2, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 5] = p1 + axis * thickness;

                triPoints [mp + 3] = mp + 3;
                triPoints [mp + 4] = mp + 4;
                triPoints [mp + 5] = mp + 5;
                uv [mp + 3]        = Misc.Vector2zero;
                uv [mp + 4]        = Misc.Vector2one;
                uv [mp + 5]        = Misc.Vector2right;

                // One side
                meshPoints [mp + 6] = meshPoints [mp + 0];
                triPoints [mp + 6]  = mp + 6;
                uv [mp + 6]         = Misc.Vector2up;
                meshPoints [mp + 7] = meshPoints [mp + 3];
                triPoints [mp + 7]  = mp + 7;
                uv [mp + 7]         = Misc.Vector2one;
                meshPoints [mp + 8] = meshPoints [mp + 1];
                triPoints [mp + 8]  = mp + 8;
                uv [mp + 8]         = Misc.Vector2zero;

                meshPoints [mp + 9]  = meshPoints [mp + 1];
                triPoints [mp + 9]   = mp + 9;
                uv [mp + 9]          = Misc.Vector2zero;
                meshPoints [mp + 10] = meshPoints [mp + 3];
                triPoints [mp + 10]  = mp + 10;
                uv [mp + 10]         = Misc.Vector2one;
                meshPoints [mp + 11] = meshPoints [mp + 5];
                triPoints [mp + 11]  = mp + 11;
                uv [mp + 11]         = Misc.Vector2zero;

                // Second side
                meshPoints [mp + 12] = meshPoints [mp + 1];
                triPoints [mp + 12]  = mp + 12;
                uv [mp + 12]         = Misc.Vector2zero;
                meshPoints [mp + 13] = meshPoints [mp + 5];
                triPoints [mp + 13]  = mp + 13;
                uv [mp + 13]         = Misc.Vector2right;
                meshPoints [mp + 14] = meshPoints [mp + 2];
                triPoints [mp + 14]  = mp + 14;
                uv [mp + 14]         = Misc.Vector2up;

                meshPoints [mp + 15] = meshPoints [mp + 2];
                triPoints [mp + 15]  = mp + 15;
                uv [mp + 15]         = Misc.Vector2up;
                meshPoints [mp + 16] = meshPoints [mp + 5];
                triPoints [mp + 16]  = mp + 16;
                uv [mp + 16]         = Misc.Vector2right;
                meshPoints [mp + 17] = meshPoints [mp + 4];
                triPoints [mp + 17]  = mp + 17;
                uv [mp + 17]         = Misc.Vector2up;

                // Third side
                meshPoints [mp + 18] = meshPoints [mp + 0];
                triPoints [mp + 18]  = mp + 18;
                uv [mp + 18]         = Misc.Vector2right;
                meshPoints [mp + 19] = meshPoints [mp + 4];
                triPoints [mp + 19]  = mp + 19;
                uv [mp + 19]         = Misc.Vector2up;
                meshPoints [mp + 20] = meshPoints [mp + 3];
                triPoints [mp + 20]  = mp + 20;
                uv [mp + 20]         = Misc.Vector2zero;

                meshPoints [mp + 21] = meshPoints [mp + 0];
                triPoints [mp + 21]  = mp + 21;
                uv [mp + 21]         = Misc.Vector2zero;
                meshPoints [mp + 22] = meshPoints [mp + 2];
                triPoints [mp + 22]  = mp + 22;
                uv [mp + 22]         = Misc.Vector2one;
                meshPoints [mp + 23] = meshPoints [mp + 4];
                triPoints [mp + 23]  = mp + 23;
                uv [mp + 23]         = Misc.Vector2up;

                mp += 24;
            }

            if (mesh == null)
            {
                mesh           = new Mesh();
                mesh.hideFlags = HideFlags.DontSave;
            }
            if (reassignMesh)
            {
                mesh.Clear();
            }
            mesh.vertices  = meshPoints;
            mesh.uv        = uv;
            mesh.triangles = triPoints;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            if (reassignMesh)
            {
                meshFilter.sharedMesh = mesh;
            }
        }