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)); }
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); } } }
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); }
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); } }
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); } } } }
public abstract void HandleTile(TileChange tileChange, System.Action <TileChange> callback = null);
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); } } } } }
public void TileRemoved(TileChange handledTileChange) { // }
public void TileHandled(TileChange handledTileChange) { activeTileChanges.Remove(new Vector3Int(handledTileChange.X, handledTileChange.Y, handledTileChange.layerIndex)); }