From 9b83b913d0949f0a3824e4eb6dd942b1b57b632f Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 10:34:42 +0100 Subject: [PATCH 1/9] cache slow sizeDelta method outside of loop --- Runtime/Scripts/WMTSMap.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index b73d492..b6afdf6 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -356,6 +356,7 @@ private void RemoveOtherLayers() /// private void UpdateLayerTiles(Dictionary tileList) { + var mapSizeDelta = rectTransformMinimapUI.sizeDelta; for(int x = 0; x <= boundsTiles.x; x++) { for(int y = 0; y <= boundsTiles.y; y++) @@ -383,8 +384,8 @@ private void UpdateLayerTiles(Dictionary tileList) float compareYPosition = yPosition * rectTransform.localScale.x + rectTransform.transform.localPosition.y; //Is this tile within the viewer rectangle? - bool xWithinView = (compareXPosition + baseTileSize > 0 && compareXPosition < rectTransformMinimapUI.sizeDelta.x); - bool yWithinView = (compareYPosition > 0 && compareYPosition - baseTileSize < rectTransformMinimapUI.sizeDelta.y); + bool xWithinView = (compareXPosition + baseTileSize > 0 && compareXPosition < mapSizeDelta.x); + bool yWithinView = (compareYPosition > 0 && compareYPosition - baseTileSize < mapSizeDelta.y); if(xWithinView && yWithinView) { From 7b200f1ea476cff9c756dd9a045d5b6bbbe7b58c Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 10:36:45 +0100 Subject: [PATCH 2/9] cache localScale and localPosition --- Runtime/Scripts/WMTSMap.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index b6afdf6..419c488 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -357,6 +357,9 @@ private void RemoveOtherLayers() private void UpdateLayerTiles(Dictionary tileList) { var mapSizeDelta = rectTransformMinimapUI.sizeDelta; + var localScale = rectTransform.localScale; + var localPosition = rectTransform.transform.localPosition; + for(int x = 0; x <= boundsTiles.x; x++) { for(int y = 0; y <= boundsTiles.y; y++) @@ -380,8 +383,8 @@ private void UpdateLayerTiles(Dictionary tileList) } //Tile position to check if they are in viewer - float compareXPosition = xPosition * rectTransform.localScale.x + rectTransform.transform.localPosition.x; - float compareYPosition = yPosition * rectTransform.localScale.x + rectTransform.transform.localPosition.y; + float compareXPosition = xPosition * localScale.x + localPosition.x; + float compareYPosition = yPosition * localScale.x + localPosition.y; //Is this tile within the viewer rectangle? bool xWithinView = (compareXPosition + baseTileSize > 0 && compareXPosition < mapSizeDelta.x); From c7863eaf44ff8ad80c9aad6e54e5795a322e36e4 Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 10:43:35 +0100 Subject: [PATCH 3/9] cache sizedelta for clamp too --- Runtime/Scripts/WMTSMap.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index 419c488..300a103 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -44,6 +44,10 @@ public class WMTSMap : MonoBehaviour [Tooltip("Defaults to Camera.main")] [SerializeField] private Camera cameraMoveTarget; + /// + /// Cached sizeDelta of the minimap + /// + private Vector2 mapSizeDelta; /// /// The current index layer of tile layers /// @@ -156,6 +160,8 @@ private void Start() private void Update() { + mapSizeDelta = rectTransformMinimapUI.sizeDelta; + Clamp(); //Continiously check if tiles of the active layer identifier should be loaded @@ -171,12 +177,12 @@ public void Clamp() var maxPositionXInUnits = -(boundsInMeters.x / startMeterInPixels) * transform.localScale.x; var maxPositionYInUnits = (boundsInMeters.y / startMeterInPixels) * transform.localScale.x; - var XPadding = rectTransformMinimapUI.sizeDelta.x*0.5f; - var YPadding = rectTransformMinimapUI.sizeDelta.y*0.5f; + var XPadding = mapSizeDelta.x*0.5f; + var YPadding = mapSizeDelta.y*0.5f; this.transform.localPosition = new Vector3( - Mathf.Clamp(this.transform.localPosition.x, maxPositionXInUnits + rectTransformMinimapUI.sizeDelta.x - XPadding, XPadding), - Mathf.Clamp(this.transform.localPosition.y, rectTransformMinimapUI.sizeDelta.y - YPadding, maxPositionYInUnits + YPadding), + Mathf.Clamp(this.transform.localPosition.x, maxPositionXInUnits + mapSizeDelta.x - XPadding, XPadding), + Mathf.Clamp(this.transform.localPosition.y, mapSizeDelta.y - YPadding, maxPositionYInUnits + YPadding), 0 ); } @@ -356,7 +362,7 @@ private void RemoveOtherLayers() /// private void UpdateLayerTiles(Dictionary tileList) { - var mapSizeDelta = rectTransformMinimapUI.sizeDelta; + mapSizeDelta = rectTransformMinimapUI.sizeDelta; var localScale = rectTransform.localScale; var localPosition = rectTransform.transform.localPosition; From 3103d8684c6d65a45b2e3e5873567e384a7979c8 Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 11:08:56 +0100 Subject: [PATCH 4/9] only calculate changes in tiles if map was moved/scaled --- Runtime/Scripts/WMTSMap.cs | 45 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index 300a103..2086206 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -121,6 +121,9 @@ public class WMTSMap : MonoBehaviour /// private Dictionary> tileLayers = new Dictionary>(); + private Vector2 lastMapSizeDelta; + private Vector3 lastMinimapPosition; + private void Awake() { if(!cameraMoveTarget) cameraMoveTarget = Camera.main; @@ -161,11 +164,15 @@ private void Start() private void Update() { mapSizeDelta = rectTransformMinimapUI.sizeDelta; - - Clamp(); - //Continiously check if tiles of the active layer identifier should be loaded - UpdateLayerTiles(tileLayers[layerIndex]); + if (mapSizeDelta != lastMapSizeDelta || transform.localPosition != lastMinimapPosition) + { + Clamp(); + UpdateLayerTiles(tileLayers[layerIndex]); + lastMapSizeDelta = mapSizeDelta; + lastMinimapPosition = transform.localPosition; + } + MovePointer(); } @@ -366,18 +373,19 @@ private void UpdateLayerTiles(Dictionary tileList) var localScale = rectTransform.localScale; var localPosition = rectTransform.transform.localPosition; - for(int x = 0; x <= boundsTiles.x; x++) + var tilesToRemove = new HashSet(); + for (int x = 0; x <= boundsTiles.x; x++) { - for(int y = 0; y <= boundsTiles.y; y++) + for (int y = 0; y <= boundsTiles.y; y++) { Vector2 tileKey; - //Tile position within this container + // Tile position within this container float xPosition = (x * tileSize) - (layerTilesOffset.x * tileSize); float yPosition = -((y * tileSize) - (layerTilesOffset.y * tileSize)); - //Origin alignment determines the way we count our grid - switch(minimapConfig.TileMatrixSet.minimapOriginAlignment) + // Origin alignment determines the way we count our grid + switch (minimapConfig.TileMatrixSet.minimapOriginAlignment) { case TileMatrixSet.OriginAlignment.BottomLeft: tileKey = new Vector2(x + tileOffset.x, (float)(divide - 1) - (y + tileOffset.y)); @@ -388,17 +396,17 @@ private void UpdateLayerTiles(Dictionary tileList) break; } - //Tile position to check if they are in viewer + // Tile position to check if they are in viewer float compareXPosition = xPosition * localScale.x + localPosition.x; float compareYPosition = yPosition * localScale.x + localPosition.y; - //Is this tile within the viewer rectangle? + // Is this tile within the viewer rectangle? bool xWithinView = (compareXPosition + baseTileSize > 0 && compareXPosition < mapSizeDelta.x); bool yWithinView = (compareYPosition > 0 && compareYPosition - baseTileSize < mapSizeDelta.y); - if(xWithinView && yWithinView) + if (xWithinView && yWithinView) { - if(!tileList.ContainsKey(tileKey)) + if (!tileList.TryGetValue(tileKey, out var existingTile)) { var newTileObject = new GameObject(); var mapTile = newTileObject.AddComponent(); @@ -407,13 +415,18 @@ private void UpdateLayerTiles(Dictionary tileList) tileList.Add(tileKey, mapTile); } } - else if(tileList.ContainsKey(tileKey)) + else if (tileList.TryGetValue(tileKey, out var tileToRemove)) { - Destroy(tileList[tileKey].gameObject); - tileList.Remove(tileKey); + tilesToRemove.Add(tileKey); } } } + + foreach (var tileKey in tilesToRemove) + { + Destroy(tileList[tileKey].gameObject); + tileList.Remove(tileKey); + } } } } From a556aefba5897d548364fdce1e4f16589372f3d4 Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 13:36:15 +0100 Subject: [PATCH 5/9] reduce garbadge --- Runtime/Scripts/Tile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Runtime/Scripts/Tile.cs b/Runtime/Scripts/Tile.cs index c6b20cd..df15810 100644 --- a/Runtime/Scripts/Tile.cs +++ b/Runtime/Scripts/Tile.cs @@ -70,7 +70,7 @@ private IEnumerator FadeInRawImage() while(TextureTargetRawImage.color.a < 1.0f) { TextureTargetRawImage.color = new Color(TextureTargetRawImage.color.r, TextureTargetRawImage.color.g, TextureTargetRawImage.color.b, TextureTargetRawImage.color.a + fadeSpeed * Time.deltaTime); - yield return new WaitForEndOfFrame(); + yield return null; } } From a03d5d15cea1d783d9e5a4b5f185afbc9b82f902 Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 14:23:10 +0100 Subject: [PATCH 6/9] log starting offsets --- Runtime/Scripts/WMTSMap.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index 2086206..8eab956 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -374,9 +374,14 @@ private void UpdateLayerTiles(Dictionary tileList) var localPosition = rectTransform.transform.localPosition; var tilesToRemove = new HashSet(); - for (int x = 0; x <= boundsTiles.x; x++) + + var startX = (int)-tileOffset.x; + var startY = (int)-tileOffset.y; + + Debug.Log("StartX: " + startX + " StartY: " + startY); + for (int x = startX; x <= boundsTiles.x; x++) { - for (int y = 0; y <= boundsTiles.y; y++) + for (int y = 0; startY <= boundsTiles.y; y++) { Vector2 tileKey; From 887458e07d3e523cb9f3c9c21eb351b35e47a3ac Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 16:58:35 +0100 Subject: [PATCH 7/9] major improvent. slightly offset --- Runtime/Scripts/WMTSMap.cs | 73 ++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index 8eab956..a3577d6 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -107,15 +107,15 @@ public class WMTSMap : MonoBehaviour /// /// The minimap UI that handles all the UI /// - private MinimapUI minimapUI; + private MinimapUI parentMinimapUI; /// /// The rect transform of the minimap /// - private RectTransform rectTransformMinimapUI; + private RectTransform parentUIRectTransform; /// /// The rect transform /// - private RectTransform rectTransform; + private RectTransform mapRectTransform; /// /// Contains the minimap layers with tiles /// @@ -128,9 +128,9 @@ private void Awake() { if(!cameraMoveTarget) cameraMoveTarget = Camera.main; - minimapUI = GetComponentInParent(); - rectTransform = GetComponent(); - rectTransformMinimapUI = (RectTransform)minimapUI.transform; + parentMinimapUI = GetComponentInParent(); + parentUIRectTransform = (RectTransform)parentMinimapUI.transform; + mapRectTransform = GetComponent(); } private void Start() @@ -163,7 +163,7 @@ private void Start() private void Update() { - mapSizeDelta = rectTransformMinimapUI.sizeDelta; + mapSizeDelta = parentUIRectTransform.sizeDelta; if (mapSizeDelta != lastMapSizeDelta || transform.localPosition != lastMinimapPosition) { @@ -247,7 +247,7 @@ public Vector3 DeterminePositionOnMap(Vector3RD sourceRDPosition) /// RD coordinate to place the object public void PositionObjectOnMap(RectTransform targetObject, Vector3RD targetPosition) { - targetObject.transform.localScale = Vector3.one / rectTransform.localScale.x; + targetObject.transform.localScale = Vector3.one / mapRectTransform.localScale.x; targetObject.transform.localPosition = DeterminePositionOnMap(targetPosition); } @@ -339,7 +339,7 @@ private void MovePointer() if(CenterPointerInView) { - this.transform.localPosition = -pointer.localPosition * rectTransform.localScale.x + (Vector3)rectTransformMinimapUI.sizeDelta * 0.5f; + this.transform.localPosition = -pointer.localPosition * mapRectTransform.localScale.x + (Vector3)parentUIRectTransform.sizeDelta * 0.5f; } } @@ -369,25 +369,29 @@ private void RemoveOtherLayers() /// private void UpdateLayerTiles(Dictionary tileList) { - mapSizeDelta = rectTransformMinimapUI.sizeDelta; - var localScale = rectTransform.localScale; - var localPosition = rectTransform.transform.localPosition; + mapSizeDelta = parentUIRectTransform.sizeDelta; + var localScale = mapRectTransform.localScale; + var localPosition = mapRectTransform.transform.localPosition; - var tilesToRemove = new HashSet(); + var tilesToRemove = new List(tileList.Keys); - var startX = (int)-tileOffset.x; - var startY = (int)-tileOffset.y; + var startX = Mathf.FloorToInt(Mathf.Max(0, -localPosition.x / (tileSize * localScale.x))); + var startY = Mathf.FloorToInt(Mathf.Max(0, localPosition.y / (tileSize * localScale.y))); - Debug.Log("StartX: " + startX + " StartY: " + startY); - for (int x = startX; x <= boundsTiles.x; x++) + var endX = Mathf.CeilToInt((mapSizeDelta.x - localPosition.x) / (tileSize * localScale.x)); + var endY = Mathf.CeilToInt((mapSizeDelta.y + localPosition.y) / (tileSize * localScale.y)); + + Debug.Log("StartX: " + startX + " StartY: " + startY + " EndX: " + endX + " EndY: " + endY); + + for (int x = startX; x <= endX; x++) { - for (int y = 0; startY <= boundsTiles.y; y++) - { + for (int y = startY; y <= endY; y++) + { Vector2 tileKey; // Tile position within this container - float xPosition = (x * tileSize) - (layerTilesOffset.x * tileSize); - float yPosition = -((y * tileSize) - (layerTilesOffset.y * tileSize)); + float tileXPosition = (x * tileSize) - (layerTilesOffset.x * tileSize); + float tileYPosition = -((y * tileSize) - (layerTilesOffset.y * tileSize)); // Origin alignment determines the way we count our grid switch (minimapConfig.TileMatrixSet.minimapOriginAlignment) @@ -402,28 +406,19 @@ private void UpdateLayerTiles(Dictionary tileList) } // Tile position to check if they are in viewer - float compareXPosition = xPosition * localScale.x + localPosition.x; - float compareYPosition = yPosition * localScale.x + localPosition.y; + float compareXPosition = tileXPosition * localScale.x + localPosition.x; + float compareYPosition = tileYPosition * localScale.x + localPosition.y; - // Is this tile within the viewer rectangle? - bool xWithinView = (compareXPosition + baseTileSize > 0 && compareXPosition < mapSizeDelta.x); - bool yWithinView = (compareYPosition > 0 && compareYPosition - baseTileSize < mapSizeDelta.y); - if (xWithinView && yWithinView) + if (!tileList.TryGetValue(tileKey, out var existingTile)) { - if (!tileList.TryGetValue(tileKey, out var existingTile)) - { - var newTileObject = new GameObject(); - var mapTile = newTileObject.AddComponent(); - mapTile.Initialize(this.transform, layerIndex, tileSize, xPosition, yPosition, tileKey, minimapConfig); - - tileList.Add(tileKey, mapTile); - } - } - else if (tileList.TryGetValue(tileKey, out var tileToRemove)) - { - tilesToRemove.Add(tileKey); + var newTileObject = new GameObject(); + var mapTile = newTileObject.AddComponent(); + mapTile.Initialize(this.transform, layerIndex, tileSize, tileXPosition, tileYPosition, tileKey, minimapConfig); + + tileList.Add(tileKey, mapTile); } + tilesToRemove.Remove(tileKey); } } From 926f466af0febba558ff882d13497a635f0e95a2 Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 17:31:21 +0100 Subject: [PATCH 8/9] remove legacy in view check --- Runtime/Scripts/WMTSMap.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Runtime/Scripts/WMTSMap.cs b/Runtime/Scripts/WMTSMap.cs index a3577d6..487d62a 100644 --- a/Runtime/Scripts/WMTSMap.cs +++ b/Runtime/Scripts/WMTSMap.cs @@ -373,15 +373,17 @@ private void UpdateLayerTiles(Dictionary tileList) var localScale = mapRectTransform.localScale; var localPosition = mapRectTransform.transform.localPosition; - var tilesToRemove = new List(tileList.Keys); - var startX = Mathf.FloorToInt(Mathf.Max(0, -localPosition.x / (tileSize * localScale.x))); - var startY = Mathf.FloorToInt(Mathf.Max(0, localPosition.y / (tileSize * localScale.y))); + var tileSizeX = tileSize * localScale.x; + var tileSizeY = tileSize * localScale.y; + + var startX = Mathf.Max(0, Mathf.FloorToInt(-localPosition.x / tileSizeX)); + var startY = Mathf.Max(0, Mathf.FloorToInt((localPosition.y-mapSizeDelta.y) / tileSizeY)); - var endX = Mathf.CeilToInt((mapSizeDelta.x - localPosition.x) / (tileSize * localScale.x)); - var endY = Mathf.CeilToInt((mapSizeDelta.y + localPosition.y) / (tileSize * localScale.y)); + var endX = Mathf.CeilToInt((mapSizeDelta.x - localPosition.x) / tileSizeX); + var endY = Mathf.FloorToInt((mapSizeDelta.y + localPosition.y) / tileSizeY); - Debug.Log("StartX: " + startX + " StartY: " + startY + " EndX: " + endX + " EndY: " + endY); + var tilesToRemove = new List(tileList.Keys); for (int x = startX; x <= endX; x++) { @@ -405,11 +407,6 @@ private void UpdateLayerTiles(Dictionary tileList) break; } - // Tile position to check if they are in viewer - float compareXPosition = tileXPosition * localScale.x + localPosition.x; - float compareYPosition = tileYPosition * localScale.x + localPosition.y; - - if (!tileList.TryGetValue(tileKey, out var existingTile)) { var newTileObject = new GameObject(); From 30ac12dc17fa3346bb3f7d53defe9fed3e1e2d9a Mon Sep 17 00:00:00 2001 From: Sam Baas Date: Tue, 13 Feb 2024 17:36:22 +0100 Subject: [PATCH 9/9] performance fixes version increment --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad86e44..ceb6db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ 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.3] - 2024-02-13 + +- Performance fixes in higher zoomlevels + ## [1.1.2] ### Removed diff --git a/package.json b/package.json index ce4e48a..90b30a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eu.netherlands3d.minimap", - "version": "1.1.2", + "version": "1.1.3", "displayName": "Netherlands3D - Minimap", "description": "A unity canvas minimap for WMTS services", "unity": "2022.2",