Skip to content

Commit

Permalink
Merge pull request #2 from Netherlands3D/fix/overlapping-buildings
Browse files Browse the repository at this point in the history
Delete left-over Game Objects when changing LOD levels and when tiles…
  • Loading branch information
mvriel authored Mar 1, 2024
2 parents d01cee9 + e8c982b commit d0d0ec6
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 155 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.1.1] - 2024-02-29

### Fixed

- GameObjects that were created after a tile had been removed are now properly destroyed
- When changing LOD levels, prior game objects are now destroyed
- Code readability improvements
- A performance improvement in determining whether a Tile needs to be destroyed when out of view

## [1.1.0] - 2024-02-24

Expand Down
118 changes: 59 additions & 59 deletions Runtime/Scripts/Layers/BinaryMeshLayer/BinaryMeshLayer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@


using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
Expand All @@ -10,7 +8,6 @@
#if SUBOBJECT
using Netherlands3D.SubObjects;
#endif
using System.Diagnostics;

namespace Netherlands3D.CartesianTiles
{
Expand Down Expand Up @@ -41,8 +38,7 @@ public override void HandleTile(TileChange tileChange, System.Action<TileChange>
switch (action)
{
case TileAction.Create:
Tile newTile = CreateNewTile(tileKey);
tiles.Add(tileKey, newTile);
tiles.Add(tileKey, CreateNewTile(tileKey));
break;
case TileAction.Upgrade:
tiles[tileKey].unityLOD++;
Expand All @@ -54,51 +50,46 @@ public override void HandleTile(TileChange tileChange, System.Action<TileChange>
InteruptRunningProcesses(tileKey);
RemoveGameObjectFromTile(tileKey);
tiles.Remove(tileKey);
callback(tileChange);
callback?.Invoke(tileChange);
return;
default:
break;
}
tiles[tileKey].runningCoroutine = StartCoroutine(DownloadBinaryMesh(tileChange, callback));
}

private Tile CreateNewTile(Vector2Int tileKey)
{
Tile tile = new Tile();
tile.unityLOD = 0;
tile.tileKey = tileKey;
tile.layer = transform.gameObject.GetComponent<Layer>();
return new Tile
{
unityLOD = 0,
tileKey = tileKey,
layer = this
};
}

private void RemoveGameObjectFromTile(Vector2Int tileKey)
{
if (!tiles.TryGetValue(tileKey, out var tile)) return;

return tile;
var tileGameObject = tile.gameObject;
if (!tileGameObject) return;

RemoveGameObject(tileGameObject);
}
private void RemoveGameObjectFromTile(Vector2Int tileKey)

private static void RemoveGameObject(GameObject tileGameObject)
{
if (tiles.ContainsKey(tileKey))
{
Tile tile = tiles[tileKey];
if (tile == null)
{
return;
}
if (tile.gameObject == null)
{
return;
}
string meshname = tile.gameObject.GetComponent<MeshFilter>().sharedMesh.name;
MeshFilter mf = tile.gameObject.GetComponent<MeshFilter>();
if (mf != null)
{
Destroy(tile.gameObject.GetComponent<MeshFilter>().sharedMesh);
}
Destroy(tiles[tileKey].gameObject);
MeshFilter mf = tileGameObject.GetComponent<MeshFilter>();
if (mf) {
Destroy(mf.sharedMesh);
}
Destroy(tileGameObject);
}

private IEnumerator DownloadBinaryMesh(TileChange tileChange, System.Action<TileChange> callback = null)
{
var tileKey = new Vector2Int(tileChange.X, tileChange.Y);
int index = tiles[tileKey].unityLOD;
var tile = tiles[tileKey];
int index = tile.unityLOD;
string url = Datasets[index].path;
if (Datasets[index].path.StartsWith("https://") || Datasets[index].path.StartsWith("file://"))
{
Expand All @@ -116,46 +107,52 @@ private IEnumerator DownloadBinaryMesh(TileChange tileChange, System.Action<Tile
webRequest.SetRequestHeader("Accept-Encoding", "br");
#endif

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

if (!tiles.ContainsKey(tileKey)) yield break;

tiles[tileKey].runningWebRequest = null;
tile.runningWebRequest = null;

if (webRequest.result != UnityWebRequest.Result.Success)
{
RemoveGameObjectFromTile(tileKey);
callback(tileChange);
callback?.Invoke(tileChange);
yield break;
}
else
{
byte[] results = webRequest.downloadHandler.data;

yield return new WaitUntil(() => pauseLoading == false);
GameObject newGameobject = CreateNewGameObject(url, results, tileChange);
if (newGameobject != null)
{
#if SUBOBJECT
if (hasMetaData)
{
yield return StartCoroutine(LoadMetaData(newGameobject, url));
}
#endif
byte[] results = webRequest.downloadHandler.data;

tiles[tileKey].gameObject = newGameobject;
yield return new WaitUntil(() => pauseLoading == false);
GameObject newGameobject = CreateNewGameObject(url, results, tileChange);

if (!newGameobject)
{
callback?.Invoke(tileChange);
yield break;
}

callback(tileChange);

}
else
if (tiles.TryGetValue(tileKey, out tile))
{
if (tile.gameObject) RemoveGameObject(tile.gameObject);

tile.gameObject = newGameobject;

#if SUBOBJECT
if (hasMetaData)
{
callback(tileChange);
yield return StartCoroutine(LoadMetaData(newGameobject, url));
}
#endif
}
else
{
// Tile was destroyed in the mean time.. destroy this game object too then.
RemoveGameObject(newGameobject);
}
}


callback?.Invoke(tileChange);
}

#if SUBOBJECT
private IEnumerator LoadMetaData(GameObject gameObject, string geometryUrl)
Expand Down Expand Up @@ -185,6 +182,9 @@ private IEnumerator LoadMetaData(GameObject gameObject, string geometryUrl)

private void ReadMetaDataFile(byte[] results, GameObject gameobject)
{
// The gameobject could be destroyed in the mean time
if (!gameobject) return;

ObjectMapping objectMapping = gameobject.AddComponent<ObjectMapping>();
objectMapping.items = new List<ObjectMappingItem>();
using (var stream = new MemoryStream(results))
Expand Down
Loading

0 comments on commit d0d0ec6

Please sign in to comment.