示例#1
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);
            }
            // 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);
                    parentObj.layer   = tilesRoot.gameObject.layer;
                    zi.tilesContainer = parentObj;
                }
            }
            else
            {
                parentObj = ti.parent.gameObject;
            }

            // Prepare mesh vertices
            Vector3[] tileCorners = new Vector3[4];
            tileCorners [0] = Conversion.GetLocalPositionFromLatLon(latLonTL);
            tileCorners [1] = Conversion.GetLocalPositionFromLatLon(new Vector2(latLonTL.x, latLonBR.y));
            tileCorners [2] = Conversion.GetLocalPositionFromLatLon(latLonBR);
            tileCorners [3] = Conversion.GetLocalPositionFromLatLon(new Vector2(latLonBR.x, latLonTL.y));
            // Add small offset to avoid seams on higher zoom levels
            if (ti.zoomLevel > 150)
            {
                const float offset = 0.00000001f;
                tileCorners [1].x += offset;
                tileCorners [2].x += offset;
                tileCorners [2].y -= offset;
                tileCorners [3].y -= offset;
            }

            // 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
        }
示例#2
0
        void CheckTilesContent(int currentZoomLevel)
        {
            int  qCount     = loadQueue.Count;
            bool cleanQueue = false;

            for (int k = 0; k < qCount; k++)
            {
                TileInfo ti = loadQueue [k];
                if (ti == null)
                {
                    cleanQueue = true;
                    continue;
                }
                if (ti.loadStatus == TILE_LOAD_STATUS.InQueue)
                {
                    if (ti.zoomLevel <= currentZoomLevel && ti.visible)
                    {
                        if (_tilePreloadTiles && ti.zoomLevel == TILE_MIN_ZOOM_LEVEL && ReloadTextureFromCacheOrMarkForDownload(ti))
                        {
                            loadQueue [k] = null;
                            cleanQueue    = true;
                            continue;
                        }
                        if (_concurrentLoads <= _tileMaxConcurrentDownloads)
                        {
                            ti.loadStatus = TILE_LOAD_STATUS.Loading;
                            _concurrentLoads++;
                            StartCoroutine(LoadTileContentBackground(ti));
                        }
                    }
                    else if (Time.time - ti.queueTime > TILE_MAX_QUEUE_TIME)
                    {
                        ti.loadStatus = TILE_LOAD_STATUS.Inactive;
                        loadQueue [k] = null;
                        cleanQueue    = true;
                    }
                }
            }

            if (cleanQueue)
            {
                if (newQueue == null)
                {
                    newQueue = new List <TileInfo> (qCount);
                }
                else
                {
                    newQueue.Clear();
                }
                for (int k = 0; k < qCount; k++)
                {
                    TileInfo ti = loadQueue [k];
                    if (ti != null)
                    {
                        newQueue.Add(ti);
                    }
                }
                loadQueue.Clear();
                loadQueue.AddRange(newQueue);
            }
        }
示例#3
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);
            }
        }
示例#4
0
        void MonitorInactiveTiles()
        {
            int  inactiveCount  = inactiveTiles.Count;
            bool changes        = false;
            bool releasedMemory = false;

            for (int k = 0; k < inactiveCount; k++)
            {
                TileInfo ti = inactiveTiles [k];
                if (ti == null || ti.gameObject == null || ti.visible || ti.texture == currentEarthTexture || ti.loadStatus != TILE_LOAD_STATUS.Loaded)
                {
                    inactiveTiles [k]    = null;
                    ti.isAddedToInactive = false;
                    changes = true;
                    continue;
                }
                if (Time.time - ti.inactiveTime > _tileKeepAlive)
                {
                    inactiveTiles [k]    = null;
                    ti.isAddedToInactive = false;
                    ti.loadStatus        = TILE_LOAD_STATUS.Inactive;
                    // tile is now invisible, setup material for when it appears again:
                    ti.ClearPlaceholderImage();
                    if (ti.source != TILE_SOURCE.Resources)
                    {
                        Destroy(ti.texture);
                    }
                    ti.texture = currentEarthTexture;
                    // Reset parentcoords on children
                    if (ti.children != null)
                    {
                        int cCount = ti.children.Count;
                        for (int c = 0; c < cCount; c++)
                        {
                            TileInfo tiChild = ti.children [c];
                            if (!tiChild.animationFinished)
                            {
                                tiChild.ClearPlaceholderImage();
                            }
                        }
                    }
                    changes        = true;
                    releasedMemory = true;
                }
            }
            if (changes)
            {
                List <TileInfo> newInactiveList = new List <TileInfo> ();
                for (int k = 0; k < inactiveCount; k++)
                {
                    if (inactiveTiles [k] != null)
                    {
                        newInactiveList.Add(inactiveTiles [k]);
                    }
                }
                inactiveTiles.Clear();
                inactiveTiles = newInactiveList;
                if (releasedMemory)
                {
                    Resources.UnloadUnusedAssets();
                    GC.Collect();
                }
            }
        }