예제 #1
0
        private void AddTileChange(TileChange tileChange, int layerIndex)
        {
            //don't add a tilechange if the tile has an active tilechange already

            Vector3Int activekey = new Vector3Int(tileChange.X, tileChange.Y, tileChange.layerIndex);

            if (activeTileChanges.ContainsKey(activekey) && tileChange.action != TileAction.Remove)
            {
                return;
            }
            bool tileIspending = false;

            for (int i = pendingTileChanges.Count - 1; i >= 0; i--)
            {
                if (pendingTileChanges[i].X == tileChange.X && pendingTileChanges[i].Y == tileChange.Y && pendingTileChanges[i].layerIndex == tileChange.layerIndex)
                {
                    tileIspending = true;
                }
            }

            //Replace running tile changes with this one if priority is higher
            if (tileIspending == false)
            {
                pendingTileChanges.Add(tileChange);
            }
        }
        public override void HandleTile(TileChange tileChange, System.Action <TileChange> callback = null)
        {
            TileAction action = tileChange.action;

            switch (action)
            {
            case TileAction.Create:
                Tile newTile = CreateNewTile(tileChange);
                tiles.Add(new Vector2Int(tileChange.X, tileChange.Y), newTile);
                break;

            case TileAction.Upgrade:
                tiles[new Vector2Int(tileChange.X, tileChange.Y)].LOD++;
                break;

            case TileAction.Downgrade:
                tiles[new Vector2Int(tileChange.X, tileChange.Y)].LOD--;
                break;

            case TileAction.Remove:
                RemoveGameObjectFromTile(tileChange);
                tiles.Remove(new Vector2Int(tileChange.X, tileChange.Y));
                callback(tileChange);
                return;

            default:
                break;
            }
            StartCoroutine(DownloadAssetBundle(tileChange, callback));
        }
        public override void HandleTile(TileChange tileChange, System.Action <TileChange> callback = null)
        {
            TileAction action  = tileChange.action;
            var        tileKey = new Vector2Int(tileChange.X, tileChange.Y);


            switch (action)
            {
            case TileAction.Create:
                Tile newTile = CreateNewTile(tileKey);
                tiles.Add(tileKey, newTile);
                break;

            case TileAction.Upgrade:
                tiles[tileKey].LOD++;
                break;

            case TileAction.Downgrade:
                tiles[tileKey].LOD--;
                break;

            case TileAction.Remove:
                InteruptRunningProcesses(tileKey);
                RemoveGameObjectFromTile(tileKey);
                tiles.Remove(tileKey);
                callback(tileChange);
                return;

            default:
                break;
            }
            tiles[tileKey].runningCoroutine = StartCoroutine(DownloadAssetBundle(tileChange, callback));
        }
예제 #4
0
        private void AbortPendingSimilarTileChanges(TileChange removeChange)
        {
            var changes = pendingTileChanges.Where(change => ((change.X == removeChange.X) && (change.Y == removeChange.Y))).ToArray();

            for (int i = changes.Length - 1; i >= 0; i--)
            {
                var runningChange = changes[i];
                layers[removeChange.layerIndex].InteruptRunningProcesses(new Vector2Int(removeChange.X, removeChange.Y));
                layers[removeChange.layerIndex].HandleTile(removeChange, TileRemoved);
                pendingTileChanges.Remove(runningChange);
            }
        }
        private GameObject CreateNewGameObject(AssetBundle assetBundle, TileChange tileChange)
        {
            container = new GameObject();

            container.name               = tileChange.X.ToString() + "-" + tileChange.Y.ToString();
            container.transform.parent   = transform.gameObject.transform;
            container.layer              = container.transform.parent.gameObject.layer;
            container.transform.position = CoordConvert.RDtoUnity(new Vector2(tileChange.X + 500, tileChange.Y + 500));

            container.SetActive(isEnabled);
            //Mesh[] meshesInAssetbundle = new Mesh[0];
            try
            {
                meshesInAssetbundle = assetBundle.LoadAllAssets <Mesh>();
            }
            catch (Exception)
            {
                Destroy(container);
                assetBundle.Unload(true);
                return(null);
            }
            mesh = meshesInAssetbundle[0];

            int count = mesh.vertexCount;

            // creating the UV-s runtime takes a lot of time and causes the garbage-collector to kick in.
            // uv's should be built in in to the meshes in the assetbundles.
            if (addHighlightuvs)
            {
                uvs = new Vector2[count];
                for (int i = 0; i < count; i++)
                {
                    uvs[i] = (defaultUV);
                }
                mesh.uv2 = uvs;
            }

            container.AddComponent <MeshFilter>().sharedMesh = mesh;

            meshRenderer = container.AddComponent <MeshRenderer>();
            meshRenderer.sharedMaterials   = DefaultMaterialList.ToArray();
            meshRenderer.shadowCastingMode = tileShadowCastingMode;

            if (createMeshcollider)
            {
                container.AddComponent <MeshCollider>().sharedMesh = mesh;
            }

            assetBundle.Unload(false);

            return(container);
        }
        private Tile CreateNewTile(TileChange tileChange)
        {
            Tile tile = new Tile();

            tile.LOD        = 0;
            tile.tileKey    = new Vector2Int(tileChange.X, tileChange.Y);
            tile.layer      = transform.gameObject.GetComponent <Layer>();
            tile.gameObject = new GameObject();
            tile.gameObject.transform.parent   = transform.gameObject.transform;
            tile.gameObject.layer              = tile.gameObject.transform.parent.gameObject.layer;
            tile.gameObject.transform.position = CoordConvert.RDtoUnity(new Vector2(tileChange.X, tileChange.Y));

            return(tile);
        }
        private IEnumerator DownloadIDMappingData(TileChange tileChange, GameObject newGameobject, System.Action <TileChange> callback = null)
        {
            Tile       tile             = tiles[new Vector2Int(tileChange.X, tileChange.Y)];
            ObjectData oldObjectMapping = tile.gameObject.GetComponent <ObjectData>();
            GameObject newTile          = newGameobject;
            string     name             = newTile.GetComponent <MeshFilter>().mesh.name;

            Debug.Log(name);
            string dataName = name.Replace(" Instance", "");

            dataName = dataName.Replace("mesh", "building");
            dataName = dataName.Replace("-", "_") + "-data";
            string dataURL = Config.activeConfiguration.buildingsMetaDataPath + dataName;

            Debug.Log(dataURL);
            ObjectMappingClass data;

            using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(dataURL))
            {
                yield return(uwr.SendWebRequest());

                if (uwr.isNetworkError || uwr.isHttpError)
                {
                    callback(tileChange);
                }
                else
                {
                    ObjectData  objectMapping  = newTile.AddComponent <ObjectData>();
                    AssetBundle newAssetBundle = DownloadHandlerAssetBundle.GetContent(uwr);
                    data = newAssetBundle.LoadAllAssets <ObjectMappingClass>()[0];

                    objectMapping.highlightIDs = oldObjectMapping.highlightIDs;
                    objectMapping.hideIDs      = oldObjectMapping.hideIDs;
                    objectMapping.ids          = data.ids;
                    objectMapping.uvs          = data.uvs;
                    objectMapping.vectorMap    = data.vectorMap;
                    objectMapping.mesh         = newTile.GetComponent <MeshFilter>().sharedMesh;
                    objectMapping.ApplyDataToIDsTexture();
                    newAssetBundle.Unload(true);
                }
            }
            yield return(new WaitUntil(() => pauseLoading == false));

            RemoveGameObjectFromTile(tileChange);
            tiles[new Vector2Int(tileChange.X, tileChange.Y)].gameObject = newGameobject;

            yield return(null);

            callback(tileChange);
        }
        private IEnumerator DownloadAssetBundle(TileChange tileChange, System.Action <TileChange> callback = null)
        {
            var    tileKey = new Vector2Int(tileChange.X, tileChange.Y);
            int    lod     = tiles[tileKey].LOD;
            string url     = Config.activeConfiguration.webserverRootPath + Datasets[lod].path;

            if (Datasets[lod].path.StartsWith("https://") || Datasets[lod].path.StartsWith("file://"))
            {
                url = Datasets[lod].path;
            }

            url = url.ReplaceXY(tileChange.X, tileChange.Y);
            var webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url);

            tiles[tileKey].runningWebRequest = webRequest;
            yield return(webRequest.SendWebRequest());

            tiles[tileKey].runningWebRequest = null;

            if (webRequest.isNetworkError || webRequest.isHttpError)
            {
                RemoveGameObjectFromTile(tileKey);
                callback(tileChange);
            }
            else
            {
                AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);
                tiles[tileKey].assetBundle = assetBundle;
                yield return(new WaitUntil(() => pauseLoading == false));

                GameObject newGameobject = CreateNewGameObject(assetBundle, tileChange);
                if (newGameobject != null)
                {
                    if (TileHasHighlight(tileChange))
                    {
                        yield return(UpdateObjectIDMapping(tileChange, newGameobject, callback));
                    }
                    else
                    {
                        RemoveGameObjectFromTile(tileKey);
                        tiles[tileKey].gameObject = newGameobject;
                        callback(tileChange);
                    }
                }
                else
                {
                    callback(tileChange);
                }
            }
        }
예제 #9
0
        private TileChange GetHighestPriorityTileChange()
        {
            TileChange highestPriorityTileChange = pendingTileChanges[0];
            float      highestPriority           = highestPriorityTileChange.priorityScore;

            for (int i = 1; i < pendingTileChanges.Count; i++)
            {
                if (pendingTileChanges[i].priorityScore > highestPriority)
                {
                    highestPriorityTileChange = pendingTileChanges[i];
                    highestPriority           = highestPriorityTileChange.priorityScore;
                }
            }
            return(highestPriorityTileChange);
        }
예제 #10
0
        void Update()
        {
            //for debugging
            //activeTileChangesView = activeTileChanges.Values.ToList();

            viewRange      = GetViewRange(cameraExtents);
            cameraPosition = GetCameraPosition(cameraExtents);

            if (tileSizes.Count == 0)
            {
                GetTilesizes();
            }
            GetTileDistancesInView(tileSizes, viewRange, cameraPosition);

            pendingTileChanges.Clear();
            RemoveOutOfViewTiles();
            GetTileChanges();

            if (pendingTileChanges.Count == 0)
            {
                return;
            }

            //Start with all remove changes to clear resources. We to all remove actions, and stop any running tilechanges that share the same position and layerindex
            InstantlyStartRemoveChanges();

            if (activeTileChanges.Count < maximumConcurrentDownloads && pendingTileChanges.Count > 0)
            {
                TileChange highestPriorityTileChange = GetHighestPriorityTileChange();
                Vector3Int tilekey = new Vector3Int(highestPriorityTileChange.X, highestPriorityTileChange.Y, highestPriorityTileChange.layerIndex);
                if (activeTileChanges.ContainsKey(tilekey) == false)
                {
                    activeTileChanges.Add(tilekey, highestPriorityTileChange);
                    pendingTileChanges.Remove(highestPriorityTileChange);
                    layers[highestPriorityTileChange.layerIndex].HandleTile(highestPriorityTileChange, TileHandled);
                }
                else if (activeTileChanges.TryGetValue(tilekey, out TileChange existingTileChange))
                {
                    //Change running tile changes to more important ones
                    Debug.Log("Upgrading existing");
                    if (existingTileChange.priorityScore < highestPriorityTileChange.priorityScore)
                    {
                        activeTileChanges[tilekey] = highestPriorityTileChange;
                        pendingTileChanges.Remove(highestPriorityTileChange);
                    }
                }
            }
        }
        private IEnumerator DownloadAssetBundle(TileChange tileChange, System.Action <TileChange> callback = null)
        {
            int    lod = tiles[new Vector2Int(tileChange.X, tileChange.Y)].LOD;
            string url = Config.activeConfiguration.webserverRootPath + Datasets[lod].path;

            if (Datasets[lod].path.StartsWith("https://"))
            {
                url = Datasets[lod].path;
            }
            url = url.Replace("{x}", tileChange.X.ToString());
            url = url.Replace("{y}", tileChange.Y.ToString());
            using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(url))
            {
                yield return(uwr.SendWebRequest());

                if (uwr.isNetworkError || uwr.isHttpError)
                {
                    RemoveGameObjectFromTile(tileChange);
                    callback(tileChange);
                }
                else
                {
                    AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(uwr);
                    yield return(new WaitUntil(() => pauseLoading == false));

                    GameObject newGameobject = CreateNewGameObject(assetBundle, tileChange);
                    if (newGameobject != null)
                    {
                        if (TileHasHighlight(tileChange))
                        {
                            StartCoroutine(DownloadIDMappingData(tileChange, newGameobject, callback));
                        }
                        else
                        {
                            RemoveGameObjectFromTile(tileChange);
                            tiles[new Vector2Int(tileChange.X, tileChange.Y)].gameObject = newGameobject;
                            callback(tileChange);
                        }
                    }
                    else
                    {
                        callback(tileChange);
                    }
                }
            }
        }
        private bool TileHasHighlight(TileChange tileChange)
        {
            Tile tile = tiles[new Vector2Int(tileChange.X, tileChange.Y)];

            if (tile.gameObject == null)
            {
                return(false);
            }
            if (tile.gameObject.GetComponent <ObjectData>() == null)
            {
                return(false);
            }
            if (tile.gameObject.GetComponent <ObjectData>().highlightIDs.Count + tile.gameObject.GetComponent <ObjectData>().hideIDs.Count == 0)
            {
                return(false);
            }

            return(true);
        }
 private void RemoveGameObjectFromTile(TileChange tileChange)
 {
     if (tiles.ContainsKey(new Vector2Int(tileChange.X, tileChange.Y)))
     {
         Tile tile = tiles[new Vector2Int(tileChange.X, tileChange.Y)];
         if (tile == null)
         {
             return;
         }
         if (tile.gameObject == null)
         {
             return;
         }
         MeshFilter mf = tile.gameObject.GetComponent <MeshFilter>();
         if (mf != null)
         {
             DestroyImmediate(tile.gameObject.GetComponent <MeshFilter>().sharedMesh, true);
         }
         Destroy(tiles[new Vector2Int(tileChange.X, tileChange.Y)].gameObject);
     }
 }
예제 #14
0
 private void RemoveOutOfViewTiles()
 {
     for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++)
     {
         // create a list of tilekeys for the tiles that are within the viewrange
         layer = layers[layerIndex];
         if (layer.gameObject.activeSelf == false)
         {
             continue;
         }
         int tilesizeIndex = tileSizes.IndexOf(layer.tileSize);
         neededTiles = tileDistances[tilesizeIndex];
         neededTileKeys.Clear();
         neededTileKeys.Capacity = neededTiles.Count;
         foreach (var neededTile in neededTiles)
         {
             //tileKey.x = neededTile.x;
             //tileKey.y = neededTile.y;
             neededTileKeys.Add(new Vector2Int(neededTile.x, neededTile.y));
         }
         //activeTiles = layer.tiles.Keys.ToArray();
         //activeTiles = new List<Vector2Int>(layer.tiles.Keys);
         // check for each active tile if the key is in the list of tilekeys within the viewrange
         foreach (var kvp in layer.tiles)
         {
             if (neededTileKeys.Contains(kvp.Key) == false)                     // if the tile is not within the viewrange, set it up for removal
             {
                 tileChange               = new TileChange();
                 tileChange.action        = TileAction.Remove;
                 tileChange.X             = kvp.Key.x;
                 tileChange.Y             = kvp.Key.y;
                 tileChange.layerIndex    = layerIndex;
                 tileChange.priorityScore = int.MaxValue;                         // set the priorityscore to maximum
                 AddTileChange(tileChange, layerIndex);
             }
         }
     }
 }
예제 #15
0
 public abstract void HandleTile(TileChange tileChange, System.Action <TileChange> callback = null);
예제 #16
0
 private void GetTileChanges()
 {
     for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++)
     {
         Layer layer = layers[layerIndex];
         if (layer.isEnabled == false)
         {
             continue;
         }
         int tilesizeIndex = tileSizes.IndexOf(layer.tileSize);
         foreach (Vector3Int tileDistance in tileDistances[tilesizeIndex])
         {
             tileKey = new Vector2Int(tileDistance.x, tileDistance.y);
             int LOD = CalculateLOD(tileDistance, layer);
             if (layer.tiles.ContainsKey(tileKey))
             {
                 int activeLOD = layer.tiles[tileKey].LOD;
                 if (LOD == -1)
                 {
                     TileChange tileChange = new TileChange();
                     tileChange.action        = TileAction.Remove;
                     tileChange.X             = tileKey.x;
                     tileChange.Y             = tileKey.y;
                     tileChange.layerIndex    = layerIndex;
                     tileChange.priorityScore = CalculatePriorityScore(layer.layerPriority, 0, tileDistance.z, TileAction.Remove);
                     AddTileChange(tileChange, layerIndex);
                 }
                 else if (activeLOD > LOD)
                 {
                     TileChange tileChange = new TileChange();
                     tileChange.action        = TileAction.Downgrade;
                     tileChange.X             = tileKey.x;
                     tileChange.Y             = tileKey.y;
                     tileChange.layerIndex    = layerIndex;
                     tileChange.priorityScore = CalculatePriorityScore(layer.layerPriority, activeLOD - 1, tileDistance.z, TileAction.Downgrade);
                     AddTileChange(tileChange, layerIndex);
                 }
                 else if (activeLOD < LOD)
                 {
                     TileChange tileChange = new TileChange();
                     tileChange.action        = TileAction.Upgrade;
                     tileChange.X             = tileKey.x;
                     tileChange.Y             = tileKey.y;
                     tileChange.layerIndex    = layerIndex;
                     tileChange.priorityScore = CalculatePriorityScore(layer.layerPriority, activeLOD + 1, tileDistance.z, TileAction.Upgrade);
                     AddTileChange(tileChange, layerIndex);
                 }
             }
             else
             {
                 if (LOD != -1)
                 {
                     TileChange tileChange = new TileChange();
                     tileChange.action        = TileAction.Create;
                     tileChange.X             = tileKey.x;
                     tileChange.Y             = tileKey.y;
                     tileChange.priorityScore = CalculatePriorityScore(layer.layerPriority, 0, tileDistance.z, TileAction.Create);
                     tileChange.layerIndex    = layerIndex;
                     AddTileChange(tileChange, layerIndex);
                 }
             }
         }
     }
 }
예제 #17
0
 public void TileRemoved(TileChange handledTileChange)
 {
     //
 }
예제 #18
0
 public void TileHandled(TileChange handledTileChange)
 {
     activeTileChanges.Remove(new Vector3Int(handledTileChange.X, handledTileChange.Y, handledTileChange.layerIndex));
 }