/// <summary> /// Returns any city near the point specified in sphere coordinates. Must be closer than CITY_HIT_PRECISION constant, usually when pointer clicks over a city icon. /// Optimized method for mouse hitting. /// </summary> /// <returns>The city near point.</returns> /// <param name="localPoint">Local point in sphere coordinates.</param> public int GetCityNearPointFast(Vector3 localPoint) { if (visibleCities == null) { return(-1); } float hitPrecision = CITY_HIT_PRECISION * _cityIconSize * 5.0f; float hitPrecisionSqr = hitPrecision * hitPrecision; Vector2 latlon = Conversion.GetLatLonFromSpherePoint(localPoint); for (int c = 0; c < countries.Length; c++) { Country country = countries [c]; if (country.regionsRect2D.Contains(latlon)) { for (int t = 0; t < visibleCities.Length; t++) { City city = visibleCities [t]; if (city.countryIndex != c) { continue; } float dist = FastVector.SqrDistance(ref city.unitySphereLocation, ref localPoint); // (city.unitySphereLocation - localPoint).sqrMagnitude; if (dist < hitPrecisionSqr) { return(GetCityIndex(city, false)); } } } } return(-1); }
/// <summary> /// Returns distance in meters from two sphere positions /// </summary> public float Distance(Vector3 position1, Vector3 position2) { Vector2 latlon1 = Conversion.GetLatLonFromSpherePoint(position1); Vector2 latlon2 = Conversion.GetLatLonFromSpherePoint(position2); return(Conversion.Distance(latlon1.x, latlon1.y, latlon2.x, latlon2.y)); }
/// <summary> /// Fills a circle centered on spherePos location with fog using alpha (transparency) and custom width. /// </summary> /// <param name="spherePos">Sphere position.</param> /// <param name="alpha">Alpha in the range 0..1.</param> /// <param name="radius">Width in the range 0..1.</param> /// <param name="strength">Strength of the brush in the range 0..1.</param> public void SetFogOfWarAlpha(Vector3 spherePos, float alpha, float radius, float strength) { Vector2 latLon = Conversion.GetLatLonFromSpherePoint(spherePos); Vector2 uv = Conversion.GetUVFromLatLon(latLon.x, latLon.y); SetFowAlpha(uv, alpha, radius, strength); }
void UpdateLatitudeLongitude() { WorldMapGlobe map = WorldMapGlobe.instance; if (map == null) { return; } latlonPending = false; _latlon = Conversion.GetLatLonFromSpherePoint(unitySphereLocation); }
public void UpdateLatLonFromSpherePoints() { int pointCount = spherePoints.Length; if (_latlon == null || _latlon.Length != pointCount) { _latlon = new Vector2[pointCount]; } for (int k = 0; k < pointCount; k++) { _latlon[k] = Conversion.GetLatLonFromSpherePoint(_spherePoints[k]); } }
/// <summary> /// Sets the color of all cells contained in a country main region. /// </summary> /// <param name="Country">Country object.</param> /// <param name="color">Color.</param> /// <param name="temporary">If set to <c>true</c> th_gridDivisionsored temporarily and returns to default color when it gets unselected.</param> public void SetCellColor(Country country, Color color, bool temporary = false) { if (country == null) { return; } Region region = country.mainRegion; for (int k = 0; k < cells.Length; k++) { Vector2 p = Conversion.GetLatLonFromSpherePoint(cells [k].sphereCenter); if (region.Contains(p)) { SetCellColor(k, color, temporary); } } }
void ComputeLatLon() { Vector3[] verts = vertices; _latlon = new Vector2[verts.Length]; Vector3 midPoint = Misc.Vector3zero; if (_latlon.Length > 0) { for (int k = 0; k < verts.Length; k++) { _latlon [k] = Conversion.GetLatLonFromSpherePoint(verts [k]); midPoint += verts[k]; } // the average lat/lon must be done in cartesian coordinates (3D) to avoid summing negative and positive latitude / longitudes which lend to incorrect average position midPoint /= verts.Length; _latlonCenter = Conversion.GetLatLonFromSpherePoint(midPoint); } }
int GetTileZoomLevel() { // Get screen dimensions of central tile int zoomLevel0 = 1; int zoomLevel1 = TILE_MAX_ZOOM_LEVEL; int zoomLevel = TILE_MIN_ZOOM_LEVEL; Vector2 latLon = Conversion.GetLatLonFromSpherePoint(GetCurrentMapLocation()); int xTile, yTile; currentTileSize = _tileSize > TILE_MIN_SIZE ? _tileSize : TILE_MIN_SIZE; currentTileSize *= (3.0f - _tileResolutionFactor); float dist = 0; for (int i = 0; i < 5; i++) { zoomLevel = (zoomLevel0 + zoomLevel1) / 2; Conversion.GetTileFromLatLon(zoomLevel, latLon.x, latLon.y, out xTile, out yTile); Vector2 latLonTL = Conversion.GetLatLonFromTile(xTile, yTile, zoomLevel); Vector2 latLonBR = Conversion.GetLatLonFromTile(xTile + 0.99f, yTile + 0.99f, zoomLevel); Vector3 spherePointTL = Conversion.GetSpherePointFromLatLon(latLonTL); Vector3 spherePointBR = Conversion.GetSpherePointFromLatLon(latLonBR); Vector3 wposTL = currentCamera.WorldToScreenPoint(transform.TransformPoint(spherePointTL)); Vector3 wposBR = currentCamera.WorldToScreenPoint(transform.TransformPoint(spherePointBR)); dist = Mathf.Max(Mathf.Abs(wposBR.x - wposTL.x), Mathf.Abs(wposTL.y - wposBR.y)); if (dist > currentTileSize) { zoomLevel0 = zoomLevel; } else { zoomLevel1 = zoomLevel; } } if (dist > currentTileSize) { zoomLevel++; } zoomLevel = Mathf.Clamp(zoomLevel, TILE_MIN_ZOOM_LEVEL, TILE_MAX_ZOOM_LEVEL); return(zoomLevel); }
/// <summary> /// Moves any point inside circle. /// </summary> /// <returns>Returns a list with changed regions</returns> public List <Region> MoveCircle(Vector3 position, Vector3 dragAmount, float circleSize) { if (entityIndex < 0 || entityIndex >= entities.Length) { return(null); } float circleSizeSqr = circleSize * circleSize; List <Region> regions = new List <Region> (100); // Current region Region currentRegion = entities [entityIndex].regions [regionIndex]; regions.Add(currentRegion); // Current region's neighbours if (!circleCurrentRegionOnly) { for (int r = 0; r < currentRegion.neighbours.Count; r++) { Region region = currentRegion.neighbours [r]; if (!regions.Contains(region)) { regions.Add(region); } } // If we're editing provinces, check if country points can be moved as well if (editingMode == EDITING_MODE.PROVINCES) { // Moves current country for (int cr = 0; cr < map.countries [countryIndex].regions.Count; cr++) { Region countryRegion = map.countries [countryIndex].regions [cr]; if (!regions.Contains(countryRegion)) { regions.Add(countryRegion); } // Moves neighbours for (int r = 0; r < countryRegion.neighbours.Count; r++) { Region region = countryRegion.neighbours [r]; if (!regions.Contains(region)) { regions.Add(region); } } } } } // Execute move operation on each point List <Region> affectedRegions = new List <Region> (regions.Count); for (int r = 0; r < regions.Count; r++) { Region region = regions [r]; bool regionAffected = false; for (int p = 0; p < region.spherePoints.Length; p++) { Vector3 rp = region.spherePoints [p]; float dist = (rp - position).sqrMagnitude; if (dist < circleSizeSqr) { if (circleMoveConstant) { region.spherePoints [p] += dragAmount; } else { region.spherePoints [p] += dragAmount - dragAmount * (dist / circleSizeSqr); } region.spherePoints [p] = region.spherePoints [p].normalized * 0.5f; Vector2 latlon = Conversion.GetLatLonFromSpherePoint(region.spherePoints [p]); region.latlon [p] = latlon; regionAffected = true; } } if (regionAffected) { affectedRegions.Add(region); } } return(affectedRegions); }
/// <summary> /// Adds the new point to currently selected region. /// </summary> public void AddPoint(Vector3 newPoint) { if (entities == null || entityIndex < 0 || entityIndex >= entities.Length || regionIndex < 0 || entities [entityIndex].regions == null || regionIndex >= entities [entityIndex].regions.Count) { return; } // List<Region> affectedRegions = new List<Region>(); Region region = entities [entityIndex].regions [regionIndex]; float minDist = float.MaxValue; int nearest = -1, previous = -1; int max = region.latlon.Length; Vector2 latlonNew = Conversion.GetLatLonFromSpherePoint(newPoint); for (int p = 0; p < max; p++) { int q = p == 0 ? max - 1 : p - 1; Vector2 rp = (region.latlon [p] + region.latlon [q]) * 0.5f; float dist = (rp - latlonNew).sqrMagnitude; // (rp.x - newPoint.x) * (rp.x - newPoint.x)*4 + (rp.y - newPoint.y) * (rp.y - newPoint.y); if (dist < minDist) { // Get nearest point minDist = dist; nearest = p; previous = q; } } if (nearest >= 0) { Vector2 latlonToInsert = (region.latlon [nearest] + region.latlon [previous]) * 0.5f; Vector3 pointToInsert = Conversion.GetSpherePointFromLatLon(latlonToInsert); pointToInsert = pointToInsert.normalized * 0.5f; // Check if nearest and previous exists in any neighbour int nearest2 = -1, previous2 = -1; for (int n = 0; n < region.neighbours.Count; n++) { Region nregion = region.neighbours [n]; for (int p = 0; p < nregion.latlon.Length; p++) { if (nregion.latlon [p] == region.latlon [nearest]) { nearest2 = p; } if (nregion.latlon [p] == region.latlon [previous]) { previous2 = p; } } if (nearest2 >= 0 && previous2 >= 0) { nregion.latlon = InsertLatLon(nregion.latlon, previous2, latlonToInsert); // affectedRegions.Add (nregion); break; } } // Insert the point in the current region (must be done after inserting in the neighbour so nearest/previous don't unsync) region.latlon = InsertLatLon(region.latlon, nearest, latlonToInsert); // affectedRegions.Add (region); } }
bool GetProvinceUnderMouse(int countryIndex, Vector3 spherePoint, out int provinceIndex, out int regionIndex) { float startingDistance = 0; provinceIndex = regionIndex = -1; Country country = countries [countryIndex]; if (country.provinces == null && _provinces == null) { ReadProvincesPackedString(); } if (country.provinces == null) { return(false); } int provincesCount = country.provinces.Length; if (provincesCount == 0) { return(false); } Vector2 mousePos; Conversion.GetLatLonFromSpherePoint(spherePoint, out mousePos); float maxArea = float.MaxValue; // Is this the same province currently selected? if (_provinceHighlightedIndex >= 0 && _provinceRegionHighlightedIndex >= 0 && _provinceHighlighted.countryIndex == countryIndex && !_provinceHighlighted.hidden) { if (_provinceRegionHighlighted.Contains(mousePos)) { maxArea = _provinceHighlighted.mainRegionArea; // cannot return yet - need to check if any other province (smaller than this) could be highlighted } } // Check other provinces for (int tries = 0; tries < 75; tries++) { float minDist = float.MaxValue; for (int p = 0; p < provincesCount; p++) { Province province = country.provinces [p]; if (province.regions == null || province.mainRegionArea > maxArea || province.hidden) { continue; } for (int pr = 0; pr < province.regions.Count; pr++) { Vector3 regionCenter = province.regions [pr].sphereCenter; float dist = FastVector.SqrDistance(ref regionCenter, ref spherePoint); // (regionCenter - spherePoint).sqrMagnitude; if (dist > startingDistance && dist < minDist) { minDist = dist; provinceIndex = GetProvinceIndex(province); regionIndex = pr; } } } // Check if this region is visible and the mouse is inside if (provinceIndex >= 0) { Region region = provinces [provinceIndex].regions [regionIndex]; if (region.Contains(mousePos)) { return(true); } } // Continue searching but farther centers startingDistance = minDist; } return(false); }