public float GetRegionZoomExtents(Region region)
        {
            // Compute world positions of region corners
            Vector2 min = region.latlonRect2D.min;
            Vector2 max = region.latlonRect2D.max;

            // Width
            Vector2 minL    = new Vector2((min.x + max.x) * 0.5f, min.y);
            Vector2 maxR    = new Vector2((min.x + max.x) * 0.5f, max.y);
            Vector3 wsLeft  = Conversion.GetSpherePointFromLatLon(minL);
            Vector3 wsRight = Conversion.GetSpherePointFromLatLon(maxR);
            float   width   = Vector3.Distance(wsLeft, wsRight);

            // Height
            Vector2 minB     = new Vector2(min.x, (max.y + min.y) * 0.5f);
            Vector2 maxT     = new Vector2(max.x, (max.y + min.y) * 0.5f);
            Vector3 wsBottom = Conversion.GetSpherePointFromLatLon(minB);
            Vector3 wsTop    = Conversion.GetSpherePointFromLatLon(maxT);
            float   height   = Vector3.Distance(wsBottom, wsTop);

            // Apply to sphere
            float scale = transform.lossyScale.x;

            return(GetFrustumZoomLevel(width * scale, height * scale));
        }
        /// <summary>
        /// Moves the gameobject obj onto the globe at the path given by latlon array and progress factor.
        /// </summary>
        /// <param name="obj">Object.</param>
        /// <param name="progress">Progress expressed in 0..1.</param>
        public void MoveTo(float progress)
        {
            // Iterate again until we reach progress
            int   steps = latLon.Count;
            float acum = 0, acumPrev = 0;

            for (int k = 0; k < steps - 1; k++)
            {
                acumPrev = acum;
                acum    += stepLengths[k] / totalLength;
                if (acum > progress)
                {
                    // This is the step where "progress" is contained.
                    if (k > 0)
                    {
                        progress = (progress - acumPrev) / (acum - acumPrev);
                    }
                    Vector3 pos0 = Conversion.GetSpherePointFromLatLon(latLon[k]);
                    Vector3 pos1 = Conversion.GetSpherePointFromLatLon(latLon[k + 1]);
                    Vector3 pos  = Vector3.Lerp(pos0, pos1, progress);
                    pos = pos.normalized * 0.5f;
                    map.AddMarker(gameObject, pos, 0.01f, false);
                    map.FlyToLocation(pos, 2f);
                    break;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Adds a line to the globe with options (returns the line gameobject).
        /// </summary>
        /// <param name="Color">line color</param>
        /// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
        /// <param name="duration">drawing speed (0 for instant drawing)</param>
        /// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
        public LineMarkerAnimator AddLine(Vector2 latLonStart, Vector2 latLonEnd, Color color, float arcElevation, float duration, float lineWidth, float fadeOutAfter)
        {
            Vector3 start = Conversion.GetSpherePointFromLatLon(latLonStart.x, latLonStart.y);
            Vector3 end   = Conversion.GetSpherePointFromLatLon(latLonEnd.x, latLonEnd.y);

            return(AddLine(start, end, color, arcElevation, duration, lineWidth, fadeOutAfter));
        }
Example #4
0
        /// <summary>
        /// Adds a line to the globe with options (returns the line gameobject).
        /// </summary>
        /// <param name="Color">line color</param>
        /// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
        /// <param name="duration">drawing speed (0 for instant drawing)</param>
        /// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
        public LineMarkerAnimator AddLine(float latitudeStart, float longitudeStart, float latitudeEnd, float longitudeEnd, Color color, float arcElevation, float duration, float lineWidth, float fadeOutAfter)
        {
            Vector3 start = Conversion.GetSpherePointFromLatLon(latitudeStart, longitudeStart);
            Vector3 end   = Conversion.GetSpherePointFromLatLon(latitudeEnd, longitudeEnd);

            return(AddLine(start, end, color, arcElevation, duration, lineWidth, fadeOutAfter));
        }
Example #5
0
        /// <summary>
        /// Moves the gameobject obj onto the globe at the path given by latlon array and progress factor.
        /// </summary>
        /// <param name="obj">Object.</param>
        /// <param name="progress">Progress expressed in 0..1.</param>
        public void MoveTo(float progress)
        {
            currentProgress = progress;  //This seems pointless
            if (latlonIndex < 0 || (latlonIndex + 1) > latLon.Count)
            {
                errorHandler.ReportError("Attempting to move beyond latlon range", ErrorState.close_window);
                return;
            }
            try
            {
                Vector3 pos0 = Conversion.GetSpherePointFromLatLon(latLon[latlonIndex]);
                Vector3 pos1 = Conversion.GetSpherePointFromLatLon(latLon[latlonIndex + 1]);
                Vector3 pos  = Vector3.Lerp(pos0, pos1, progress);
                pos = pos.normalized * 0.5f;
                float playerSize = AnimatedObject.Size;
                worldMapGlobe.AddMarker(gameObject, pos, playerSize, false);

                // Make it look towards destination
                Vector3 dir  = (pos0 - pos1).normalized;
                Vector3 proj = Vector3.ProjectOnPlane(dir, pos0);
                transform.LookAt(worldMapGlobe.transform.TransformPoint(proj + pos0), worldMapGlobe.transform.transform.TransformDirection(pos0));
            }
            catch (System.Exception ex)
            {
                errorHandler.CatchException(ex, ErrorState.close_window);
            }
        }
        public void SetVertices(Vector2[] latlon)
        {
            if (latlon == null || latlon.Length < 2)
            {
                return;
            }

            Vector3[] spherePoints = new Vector3[latlon.Length];
            for (int k = 0; k < latlon.Length; k++)
            {
                spherePoints [k] = Conversion.GetSpherePointFromLatLon(latlon [k]);
            }
            startAltitude = spherePoints [0].magnitude;
            endAltitude   = spherePoints [latlon.Length - 1].magnitude;

            this.start = spherePoints [0];
            this.end   = spherePoints [latlon.Length - 1];

            Vector3 start, end;

            vertices = new Vector3[numPoints];
            for (int s = 0; s < numPoints; s++)
            {
                float   t         = (float)s / (numPoints - 1);
                float   elevation = Mathf.Sin(t * Mathf.PI) * arcElevation;
                Vector3 sPos;
                float   h = Mathf.Lerp(startAltitude, endAltitude, t);

                float t2;
                if (t >= 1f)
                {
                    t2    = 1f;
                    start = end = spherePoints [latlon.Length - 1];
                }
                else
                {
                    float ft    = (latlon.Length - 1) * t;
                    int   index = (int)ft;
                    int   prev  = index;
                    int   pos   = prev + 1;
                    if (pos >= latlon.Length)
                    {
                        pos = latlon.Length - 1;
                    }
                    start = spherePoints [prev];
                    end   = spherePoints [pos];
                    t2    = ft - index;
                }
                if (earthInvertedMode)
                {
                    sPos = Vector3.Lerp(start, end, t2).normalized *h *(1.0f - elevation);
                }
                else
                {
                    sPos = Vector3.Lerp(start, end, t2).normalized *h *(1.0f + elevation);
                }
                vertices [s] = sPos;
            }
        }
Example #7
0
        /// <summary>
        /// Gets the cell under the latlon position
        /// </summary>
        public int GetCellIndex(Vector2 latlon)
        {
            if (cells == null)
            {
                return(-1);
            }
            Vector3 spherePosition = Conversion.GetSpherePointFromLatLon(latlon);

            return(GetCellAtLocalPosition(spherePosition, false));
        }
Example #8
0
        public void addMarker(TweetObject tweet)
        {
            GameObject cube           = GameObject.CreatePrimitive(PrimitiveType.Cube);
            Vector3    sphereLocation = Conversion.GetSpherePointFromLatLon(new Vector2(tweet.getTweetLat(), tweet.getTweetLong()));

            //GameObject obj = map.AddMarker(MARKER_TYPE.CIRCLE, sphereLocation, kmRadius, ringWidthStart, ringWidthEnd, Color.green);
            map.AddMarker(cube, sphereLocation, 0.001f);

            tweet.setGameObject(cube);
        }
Example #9
0
        public void UpdateSpherePointsFromLatLon()
        {
            int pointCount = latlon.Length;

            if (spherePoints == null || spherePoints.Length != pointCount)
            {
                _spherePoints = new Vector3[pointCount];
            }

            for (int k = 0; k < pointCount; k++)
            {
                _spherePoints[k] = Conversion.GetSpherePointFromLatLon(_latlon[k]);
            }
        }
Example #10
0
        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);
        }
Example #11
0
        void Start()
        {
            float latitude  = 40.71f;
            float longitude = -74f;

            WorldMapGlobe map            = WorldMapGlobe.instance;
            Vector3       sphereLocation = Conversion.GetSpherePointFromLatLon(latitude, longitude);

            // Create sprite
            destinationSprite = new GameObject();
            SpriteRenderer dest_sprite = destinationSprite.AddComponent <SpriteRenderer> ();

            dest_sprite.sprite = Resources.Load <Sprite> ("NewYork");

            // Add sprite billboard to the map with custom scale, billboard mode and little bit elevated from surface (to prevent clipping with city spots)
            map.AddMarker(destinationSprite, sphereLocation, 0.02f, true, 0.1f);

            // Add click handlers
            destinationSprite.AddComponent <SpriteClickHandler> ();

            // Locate it on the map
            map.FlyToLocation(sphereLocation, 4f, 0.4f);
            map.autoRotationSpeed = 0f;
        }
        /// <summary>
        /// Moves the gameobject obj onto the globe at the path given by latlon array and progress factor.
        /// </summary>
        /// <param name="obj">Object.</param>
        /// <param name="progress">Progress expressed in 0..1.</param>
        public void MoveTo(float progress)
        {
            currentProgress = progress;

            // Iterate again until we reach progress
            int   steps = latLon.Count;
            float acum = 0, acumPrev = 0;

            for (int k = 0; k < steps - 1; k++)
            {
                acumPrev = acum;
                acum    += stepLengths [k] / totalLength;
                if (acum > progress)
                {
                    // This is the step where "progress" is contained.
                    if (k > 0)
                    {
                        progress = (progress - acumPrev) / (acum - acumPrev);
                    }
                    Vector3 pos0 = Conversion.GetSpherePointFromLatLon(latLon [k]);
                    Vector3 pos1 = Conversion.GetSpherePointFromLatLon(latLon [k + 1]);
                    Vector3 pos  = Vector3.Lerp(pos0, pos1, progress);
                    pos = pos.normalized * 0.5f;
                    map.AddMarker(gameObject, pos, 0.01f, false);

                    // Make it look towards destination
                    Vector3 dir  = (pos1 - pos0).normalized;
                    Vector3 proj = Vector3.ProjectOnPlane(dir, pos0);
                    transform.LookAt(map.transform.TransformPoint(proj + pos0), map.transform.transform.TransformDirection(pos0));

                    // Follow object
                    map.FlyToLocation(pos, 0f);
                    break;
                }
            }
        }
Example #13
0
        GameObject GenerateProvinceRegionSurface(int provinceIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation, bool temporary)
        {
            if (provinceIndex < 0 || provinceIndex >= provinces.Length)
            {
                return(null);
            }
            if (provinces [provinceIndex].regions == null)
            {
                ReadProvincePackedString(provinces [provinceIndex]);
            }
            if (provinces [provinceIndex].regions == null || regionIndex < 0 || regionIndex >= provinces [provinceIndex].regions.Count)
            {
                return(null);
            }

            Province province = provinces [provinceIndex];
            Region   region   = province.regions [regionIndex];

            if (!temporary)
            {
                region.customMaterial        = material;
                region.customTextureOffset   = textureOffset;
                region.customTextureRotation = textureRotation;
                region.customTextureScale    = textureScale;
                UpdateSurfaceCount();
            }


            // Triangulate to get the polygon vertex indices
            Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.latlon);

            if (_enableProvinceEnclaves && regionIndex == province.mainRegionIndex)
            {
                ProvinceSubstractProvinceEnclaves(provinceIndex, region, poly);
            }

            // Antarctica, Saskatchewan (Canada), British Columbia (Canada), Krasnoyarsk (Russia) - special cases due to its geometry
            float step = _frontiersDetail == FRONTIERS_DETAIL.High ? 2f : 5f;

            if (steinerPoints == null)
            {
                steinerPoints = new List <TriangulationPoint> (1000);
            }
            else
            {
                steinerPoints.Clear();
            }
            float x0 = region.latlonRect2D.min.x + step / 2f;
            float x1 = region.latlonRect2D.max.x - step / 2f;
            float y0 = region.latlonRect2D.min.y + step / 2f;
            float y1 = region.latlonRect2D.max.y - step / 2f;

            for (float x = x0; x < x1; x += step)
            {
                for (float y = y0; y < y1; y += step)
                {
                    float xp = x + UnityEngine.Random.Range(-0.0001f, 0.0001f);
                    float yp = y + UnityEngine.Random.Range(-0.0001f, 0.0001f);
                    if (region.Contains(xp, yp))
                    {
                        steinerPoints.Add(new TriangulationPoint(xp, yp));
                        //						GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                        //						obj.transform.SetParent(WorldMapGlobe.instance.transform, false);
                        //						obj.transform.localScale = Vector3.one * 0.01f;
                        //						obj.transform.localPosition = Conversion.GetSpherePointFromLatLon(new Vector2(x,y)) * 1.01f;
                    }
                }
            }
            if (steinerPoints.Count > 0)
            {
                poly.AddSteinerPoints(steinerPoints);
            }
            P2T.Triangulate(poly);

            int flip1, flip2;

            if (_earthInvertedMode)
            {
                flip1 = 2;
                flip2 = 1;
            }
            else
            {
                flip1 = 1;
                flip2 = 2;
            }
            int triCount = poly.Triangles.Count;

            Vector3[] revisedSurfPoints = new Vector3[triCount * 3];
            for (int k = 0; k < triCount; k++)
            {
                DelaunayTriangle dt = poly.Triangles [k];
                revisedSurfPoints [k * 3]         = Conversion.GetSpherePointFromLatLon(dt.Points [0].X, dt.Points [0].Y);
                revisedSurfPoints [k * 3 + flip1] = Conversion.GetSpherePointFromLatLon(dt.Points [1].X, dt.Points [1].Y);
                revisedSurfPoints [k * 3 + flip2] = Conversion.GetSpherePointFromLatLon(dt.Points [2].X, dt.Points [2].Y);
            }

            int revIndex = revisedSurfPoints.Length - 1;

            // Generate surface mesh
            int        cacheIndex = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex);
            GameObject surf       = Drawing.CreateSurface(SURFACE_GAMEOBJECT, revisedSurfPoints, revIndex, material, region.rect2Dbillboard, textureScale, textureOffset, textureRotation);

            surf.transform.SetParent(surfacesLayer.transform, false);
            surf.transform.localPosition = Misc.Vector3zero;
            if (_earthInvertedMode)
            {
                surf.transform.localScale = Misc.Vector3one * 0.998f;
            }
            surfaces [cacheIndex] = surf;
            return(surf);
        }
Example #14
0
        void CreateTile(TileInfo ti)
        {
            Vector2       latLonTL = ti.latlons [0];
            Vector2       latLonBR;
            ZoomLevelInfo zi       = zoomLevelsInfo [ti.zoomLevel];
            int           tileCode = GetTileHashCode(ti.x + 1, ti.y + 1, ti.zoomLevel);

            if (cachedTiles.ContainsKey(tileCode))
            {
                latLonBR = cachedTiles [tileCode].latlons [0];
            }
            else
            {
                latLonBR = GetLatLonFromTile(ti.x + 1, ti.y + 1, ti.zoomLevel);
            }

            // Create container
            GameObject parentObj;

            if (ti.parent == null)
            {
                parentObj = zi.tilesContainer;
                if (parentObj == null)
                {
                    parentObj = new GameObject("Tiles" + ti.zoomLevel);
                    parentObj.transform.SetParent(tilesRoot, false);
                    zi.tilesContainer = parentObj;
                }
            }
            else
            {
                parentObj = ti.parent.gameObject;
            }

            // Prepare mesh vertices
            Vector3[] tileCorners = new Vector3[4];
            tileCorners [0] = Conversion.GetSpherePointFromLatLon(latLonTL);
            tileCorners [1] = Conversion.GetSpherePointFromLatLon(new Vector2(latLonTL.x, latLonBR.y));
            tileCorners [2] = Conversion.GetSpherePointFromLatLon(latLonBR);
            tileCorners [3] = Conversion.GetSpherePointFromLatLon(new Vector2(latLonBR.x, latLonTL.y));

            Vector2[] meshUV;
            if (ti.zoomLevel < TILE_MIN_ZOOM_LEVEL)
            {
                Vector2[] uv = new Vector2[4];
                uv [0] = new Vector2((latLonTL.y + 180) / 360f, (latLonTL.x + 90) / 180f);
                uv [1] = new Vector2((latLonBR.y + 180) / 360f, (latLonTL.x + 90) / 180f);
                uv [2] = new Vector2((latLonBR.y + 180) / 360f, (latLonBR.x + 90) / 180f);
                uv [3] = new Vector2((latLonTL.y + 180) / 360f, (latLonBR.x + 90) / 180f);
                meshUV = uv;
            }
            else
            {
                meshUV = tileUV;
            }

            Material tileMat;

            if (ti.parent != null)
            {
                if (ti.parent.normalMat == null)
                {
                    ti.parent.normalMat           = Instantiate(tileMatRef);
                    ti.parent.normalMat.hideFlags = HideFlags.DontSave;
                }
                if (ti.zoomLevel < TILE_MIN_ZOOM_LEVEL)
                {
                    tileMat = ti.parent.normalMat;
                }
                else
                {
                    if (ti.parent.transMat == null)
                    {
                        ti.parent.transMat           = Instantiate(tileMatTransRef);
                        ti.parent.transMat.hideFlags = HideFlags.DontSave;
                    }
                    tileMat = ti.parent.transMat;
                }
            }
            else
            {
                ti.normalMat           = Instantiate(tileMatRef);
                ti.normalMat.hideFlags = HideFlags.DontSave;
                tileMat = ti.normalMat;
            }
            ti.renderer   = CreateObject(parentObj.transform, "Tile", tileCorners, tileIndices, meshUV, tileMat, ti.subquadIndex);
            ti.gameObject = ti.renderer.gameObject;
            ti.created    = true;
        }
Example #15
0
        void CreateTile(TileInfo ti)
        {
            Vector2       latLonTL = ti.latlons [0];
            Vector2       latLonBR;
            ZoomLevelInfo zi       = zoomLevelsInfo [ti.zoomLevel];
            int           tileCode = GetTileHashCode(ti.x + 1, ti.y + 1, ti.zoomLevel);
            TileInfo      cachedTile;

            if (cachedTiles.TryGetValue(tileCode, out cachedTile))
            {
                latLonBR = cachedTile.latlons [0];
            }
            else
            {
                latLonBR = Conversion.GetLatLonFromTile(ti.x + 1, ti.y + 1, ti.zoomLevel);
            }
            // Avoid seams on very close distance to surface
            if (ti.zoomLevel >= 16)
            {
                float tao = 0.000002f * (ti.zoomLevel - 15);
                latLonTL.x += tao;
                latLonTL.y -= tao;
                latLonBR.x -= tao;
                latLonBR.y += tao;
            }

            // Create container
            GameObject parentObj;

            if (ti.parent == null)
            {
                parentObj = zi.tilesContainer;
                if (parentObj == null)
                {
                    parentObj = new GameObject("Tiles" + ti.zoomLevel);
                    parentObj.transform.SetParent(tilesRoot, false);
                    zi.tilesContainer = parentObj;
                }
            }
            else
            {
                parentObj = ti.parent.gameObject;
            }

            // Prepare mesh vertices
            Vector3[] tileCorners = new Vector3[4];
            tileCorners [0] = Conversion.GetSpherePointFromLatLon(latLonTL);
            tileCorners [1] = Conversion.GetSpherePointFromLatLon(new Vector2(latLonTL.x, latLonBR.y));
            tileCorners [2] = Conversion.GetSpherePointFromLatLon(latLonBR);
            tileCorners [3] = Conversion.GetSpherePointFromLatLon(new Vector2(latLonBR.x, latLonTL.y));

            // Setup tile materials
            TileInfo parent = ti.parent != null ? ti.parent : ti;

            if (parent.normalMat == null)
            {
                parent.normalMat           = Instantiate(tileMatRef);
                parent.normalMat.hideFlags = HideFlags.DontSave;
            }
            if (parent.transMat == null)
            {
                parent.transMat           = Instantiate(tileMatTransRef);
                parent.transMat.hideFlags = HideFlags.DontSave;
            }

            Material tileMat = ti.zoomLevel < TILE_MIN_ZOOM_LEVEL ? parent.normalMat : parent.transMat;

            // UVs wrt Earth texture
            Vector2 tl = new Vector2((latLonTL.y + 180) / 360f, (latLonTL.x + 90) / 180f);
            Vector2 br = new Vector2((latLonBR.y + 180) / 360f, (latLonBR.x + 90) / 180f);

            if (tl.x > 0.5f && br.x < 0.5f)
            {
                br.x = 1f;
            }
            ti.worldTextureCoords = new Vector4(tl.x, br.y, br.x, tl.y);
            ti.ClearPlaceholderImage();

            if (ti.zoomLevel < TILE_MIN_ZOOM_LEVEL)
            {
                ti.loadStatus = TILE_LOAD_STATUS.Loaded;
            }
            ti.texture = currentEarthTexture;

            ti.renderer         = CreateObject(parentObj.transform, "Tile", tileCorners, tileIndices, tileUV, tileMat, ti.subquadIndex);
            ti.gameObject       = ti.renderer.gameObject;
            ti.renderer.enabled = false;
            ti.created          = true;

#if DEBUG_TILES
            ti.gameObject.AddComponent <TileInfoEx> ();
#endif
        }
Example #16
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;
                    Vector3 spherePos = Conversion.GetSpherePointFromLatLon(latlon);
                    ti.spherePos [k] = spherePos;
                }
                cachedTiles [tileCode] = ti;
            }
            // Check if any tile corner is visible
            // Phase I
#if DEBUG_TILES
            if (ti.gameObject != null && ti.gameObject.GetComponent <TileInfoEx> ().debug)
            {
                Debug.Log("this");
            }
#endif

            bool    cornersOccluded = true;
            Vector3 minWorldPos     = Misc.Vector3Max;
            Vector3 maxWorldPos     = Misc.Vector3Min;
            Vector3 tmp             = Misc.Vector3zero;
            for (int c = 0; c < 4; c++)
            {
                Vector3 wpos = transform.TransformPoint(ti.spherePos [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;
                }
                if (cornersOccluded)
                {
                    float radiusSqr = (wpos.x - globePos.x) * (wpos.x - globePos.x) + (wpos.y - globePos.y) * (wpos.y - globePos.y) + (wpos.z - globePos.z) * (wpos.z - globePos.z);                     //  Vector3.SqrMagnitude (wpos - globePos);
//																				Vector3 camDir = (currentCameraPosition - wpos).normalized;
                    FastVector.NormalizedDirection(ref wpos, ref currentCameraPosition, ref tmp);
//																				Vector3 st = wpos + ndir * (0.01f * transform.localScale.x);
                    Vector3 st = wpos;
                    FastVector.Add(ref st, ref tmp, localScaleFactor);
                    float mag = (st.x - globePos.x) * (st.x - globePos.x) + (st.y - globePos.y) * (st.y - globePos.y) + (st.z - globePos.z) * (st.z - globePos.z);
                    if (mag > radiusSqr)
                    {
                        cornersOccluded = false;
                    }
                }
            }

//												Bounds bounds = new Bounds ((minWorldPos + maxWorldPos) * 0.5f, maxWorldPos - minWorldPos);
            FastVector.Average(ref minWorldPos, ref maxWorldPos, ref tmp);
            Bounds  bounds       = new Bounds(tmp, maxWorldPos - minWorldPos);
            Vector3 tileMidPoint = bounds.center;
            // Check center of quad
            if (cornersOccluded)
            {
                float radiusSqr = (tileMidPoint.x - globePos.x) * (tileMidPoint.x - globePos.x) + (tileMidPoint.y - globePos.y) * (tileMidPoint.y - globePos.y) + (tileMidPoint.z - globePos.z) * (tileMidPoint.z - globePos.z);                 // Vector3.SqrMagnitude (tileMidPoint - globePos);
//																Vector3 camDir = (currentCameraPosition - tileMidPoint).normalized;
                FastVector.NormalizedDirection(ref tileMidPoint, ref currentCameraPosition, ref tmp);
//																Vector3 st = tileMidPoint + tmp * (0.01f * transform.localScale.x);
                Vector3 st = tileMidPoint;
                FastVector.Add(ref st, ref tmp, localScaleFactor);
                float mag = (st.x - globePos.x) * (st.x - globePos.x) + (st.y - globePos.y) * (st.y - globePos.y) + (st.z - globePos.z) * (st.z - globePos.z);
                if (mag > radiusSqr)
                {
                    cornersOccluded = false;
                }
            }

#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;
            if (!cornersOccluded)
            {
                // Phase II
                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);
                }
            }

            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
                bool tileIsBig = false;
                FastVector.NormalizedDirection(ref globePos, ref tileMidPoint, ref tmp);
//																float dd = Vector3.Dot (currentCameraForward, (tileMidPoint - globePos).normalized);
                float dd = Vector3.Dot(currentCameraForward, tmp);
                if (dd > -0.8f || currentZoomLevel > 9)                   // prevents big seams on initial zooms
                {
                    float aparentSize = Mathf.Max(maxX - minX, maxY - minY);
                    tileIsBig = aparentSize > currentTileSize;
                }
                else
                {
                    tileIsBig = ti.zoomLevel < currentZoomLevel;
                }

                                #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);
            }
        }
Example #17
0
        void CreatePole(TileInfo ti)
        {
            Vector3 polePos;
            Vector3 latLon0;
            string  name;
            bool    isNorth = (ti.y == 0);

            if (isNorth)
            {
                if (northPoleObj != null)
                {
                    return;
                }
                polePos = Misc.Vector3up * 0.5f;
                latLon0 = ti.latlons [0];
                name    = "North Pole";
            }
            else
            {
                if (southPoleObj != null)
                {
                    return;
                }
                polePos = Misc.Vector3down * 0.5f;
                latLon0 = ti.latlons [2];
                name    = "South Pole";
            }
            Vector3 latLon3 = latLon0;
            float   lonDX   = 360f / zoomLevelsInfo [ti.zoomLevel].xMax;

            latLon3.y += lonDX;
            int            steps       = (int)(360f / lonDX);
            int            vertexCount = steps * 3;
            List <Vector3> vertices    = new List <Vector3> (vertexCount);
            List <int>     indices     = new List <int> (vertexCount);
            List <Vector2> uv          = new List <Vector2> (vertexCount);

            for (int k = 0; k < steps; k++)
            {
                Vector3 p0 = Conversion.GetSpherePointFromLatLon(latLon0);
                Vector3 p1 = Conversion.GetSpherePointFromLatLon(latLon3);
                latLon0    = latLon3;
                latLon3.y += lonDX;
                vertices.Add(p0);
                vertices.Add(p1);
                vertices.Add(polePos);
                indices.Add(k * 3);
                if (isNorth)
                {
                    indices.Add(k * 3 + 2);
                    indices.Add(k * 3 + 1);
                }
                else
                {
                    indices.Add(k * 3 + 1);
                    indices.Add(k * 3 + 2);
                }
                uv.Add(Misc.Vector2zero);
                uv.Add(Misc.Vector2up);
                uv.Add(Misc.Vector2right);
            }
            Renderer obj = CreateObject(tilesRoot.transform, name, vertices.ToArray(), indices.ToArray(), uv.ToArray(), ti.parent.normalMat, 0);

            if (isNorth)
            {
                northPoleObj = obj;
            }
            else
            {
                southPoleObj = obj;
            }
        }
Example #18
0
        /// <summary>
        /// Returns the index of the nearest city to a location (lat/lon).
        /// </summary>
        public int GetCityIndex(float lat, float lon)
        {
            Vector3 spherePosition = Conversion.GetSpherePointFromLatLon(lat, lon);

            return(GetCityIndex(spherePosition));
        }
Example #19
0
        /// <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);
            }
        }
        /// <summary>
        /// Navigates to target latitude and longitude using given duration.
        /// </summary>
        public void FlyToLocation(float latitude, float longitude, float duration, float destinationZoomLevel = 0)
        {
            Vector3 destination = Conversion.GetSpherePointFromLatLon(latitude, longitude);

            FlyToLocation(destination, duration, destinationZoomLevel, _navigationBounceIntensity);
        }
        /// <summary>
        /// Navigates to target latitude and longitude using given duration.
        /// </summary>
        public void FlyToLocation(float latitude, float longitude, float duration)
        {
            Vector3 destination = Conversion.GetSpherePointFromLatLon(latitude, longitude);

            FlyToLocation(destination, duration);
        }
Example #22
0
//		GameObject root;

        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.ContainsKey(tileCode))
            {
                ti = cachedTiles [tileCode];
            }
            else
            {
                ti        = new TileInfo(xTile, yTile, zoomLevel, subquadIndex);
                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 = GetLatLonFromTile(xTile + offsets [k].x, yTile + offsets [k].y, zoomLevel);
                    ti.latlons [k] = latlon;
                    Vector3 spherePos = Conversion.GetSpherePointFromLatLon(latlon);
                    ti.spherePos [k] = spherePos;
                }
                cachedTiles [tileCode] = ti;
            }
            // Check if any tile corner is visible
            // Phase I
//			float distCam = Vector3.SqrMagnitude ((transform.position - Camera.main.transform.position) * 0.95f);
//			float distCam = Vector3.Distance (transform.position, Camera.main.transform.position) * 0.95f; // ((transform.position - Camera.main.transform.position) * 0.95f);

            bool cornersOccluded = true;

            for (int c = 0; c < 4; c++)
            {
                ti.cornerWorldPos [c] = transform.TransformPoint(ti.spherePos [c]);
                if (cornersOccluded)
                {
                    float   radiusSqr = Vector3.SqrMagnitude(ti.cornerWorldPos [c] - transform.position);
                    Vector3 camDir    = (Camera.main.transform.position - ti.cornerWorldPos [c]).normalized;
                    Vector3 st        = ti.cornerWorldPos [c] + camDir * 0.01f;
                    if (Vector3.SqrMagnitude(st - transform.position) > radiusSqr)
                    {
//					if ( Vector3.SqrMagnitude (ti.cornerWorldPos [c] - Camera.main.transform.position) < distCam) {
                        cornersOccluded = false;
                    }
                }
            }

            bool  insideViewport = false;
            float minX = 2f, minY = 2f, maxX = -2f, maxY = -2f, maxZ = -1;

            if (!cornersOccluded)
            {
                // Phase II

                for (int c = 0; c < 4; c++)
                {
                    Vector3 scrPos = Camera.main.WorldToViewportPoint(ti.cornerWorldPos [c]);
                    if (scrPos.z < 0)
                    {
                        scrPos.x *= -1f;
                        scrPos.y *= -1f;
                    }
                    insideViewport = insideViewport || (scrPos.z > 0 && scrPos.x >= 0 && scrPos.x < 1f && scrPos.y >= 0 && scrPos.y < 1);
                    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 (scrPos.z > maxZ)
                    {
                        maxZ = scrPos.z;
                    }
                }
                if (!insideViewport && maxZ > 0)
                {
                    // Check if rectangles overlap
                    insideViewport = !(minX > 1 || maxX < 0 || minY > 1 || maxY < 0);                           // completely outside of screen?
                }
            }

            if (ti.debug)
            {
                Debug.Log("this");
            }

            ti.insideViewport = insideViewport;
            ti.visible        = false;
            if (insideViewport)
            {
//				if (root==null) {
//					root = new GameObject();
//					root.transform.SetParent(transform);
//					root.transform.localPosition = Vector3.zero;
//					root.transform.localRotation = Quaternion.Euler(0,0,0);
//				}

                if (!ti.created)
                {
                    CreateTile(ti);
                }
                if (!ti.gameObject.activeSelf)
                {
                    ti.gameObject.SetActive(true);
                }
                float aparentSize = Mathf.Max((maxX - minX) * (float)Camera.main.pixelWidth, (maxY - minY) * (float)Camera.main.pixelHeight);
                bool  tileIsBig   = aparentSize > currentTileSize;

//				if (zoomLevel < currentZoomLevel && (tileIsBig || zoomLevel<TILE_MIN_ZOOM_LEVEL)) {
                if (tileIsBig || zoomLevel < TILE_MIN_ZOOM_LEVEL)
                {
//					if (tileIsBig) {
//					GameObject mark = GameObject.CreatePrimitive(PrimitiveType.Cube);
//					mark.transform.SetParent(root.transform);
//					mark.transform.position = ti.cornerWorldPos[0];
//					mark.transform.localScale = Vector3.one * 0.3f;
//					TileInfoEx tie = mark.AddComponent<TileInfoEx>();
//					tie.maxX = aparentSize;
//					}

                    // 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);
                    // Should I hide this tile? Only if children are all loaded
                    bool allLoaded = true;
                    if (ti.children != null)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            TileInfo children = ti.children [k];
                            if (children.insideViewport)
                            {
                                allLoaded = allLoaded && children.isLoadedOrHasAllChildrenLoaded;
                            }
                            if (!allLoaded)
                            {
                                break;
                            }
                        }
                    }
                    ti.isLoadedOrHasAllChildrenLoaded = allLoaded;
                    ti.renderer.enabled = !allLoaded && (ti.loadStatus == TILE_LOAD_STATUS.Loaded || zoomLevel < TILE_MIN_ZOOM_LEVEL);
                    if (ti.parent != null && ti.renderer.enabled && ti.renderer.sharedMaterial == ti.parent.transMat)
                    {
                        ti.renderer.sharedMaterial = ti.parent.normalMat;
                    }
                }
                else
                {
                    ti.visible = true;
                    if (ti.loadStatus == TILE_LOAD_STATUS.Loaded)
                    {
                        if (!ti.renderer.enabled)
                        {
                            ShowTile(ti);
                        }
                    }
                    else
                    {
                        if (ti.loadStatus == TILE_LOAD_STATUS.Inactive)
                        {
                            ti.distToCamera = (ti.cornerWorldPos [0] - Camera.main.transform.position).sqrMagnitude * ti.zoomLevel;
                            ti.loadStatus   = TILE_LOAD_STATUS.InQueue;
                            ti.queueTime    = Time.time;
                            loadQueue.Add(ti);
                        }
                        if (ti.renderer.enabled)
                        {
                            ti.renderer.enabled = false;
                        }
                    }
                    ti.isLoadedOrHasAllChildrenLoaded = ti.renderer.enabled && ti.animationFinished;
                    if (ti.children != null)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            TileInfo tiChild = ti.children [k];
                            if (tiChild.gameObject != null && tiChild.gameObject.activeSelf)
                            {
                                tiChild.gameObject.SetActive(false);
                                ti.visible = false;
                            }
                        }
                    }
                }
            }
            else
            {
                if (ti.gameObject != null && ti.gameObject.activeSelf)
                {
                    ti.gameObject.SetActive(false);
//					if (ti.texture!=null) {
//						Destroy(ti.texture);
//						ti.texture = null;
//						ti.loadStatus = TILE_LOAD_STATUS.Inactive;
//						if (gcCount++>100) {
//							gcCount = 0;
//							Resources.UnloadUnusedAssets();
//							System.GC.Collect();
//							Debug.Log ("Gc collect!");
//						}
//					}
                }
            }
//			if (ti.visible) {
//				visibleTiles++;
//			}
        }