Select to view content in your preferred language

Terrain tiles get misplaced when changing tabletop map center under certain circumstances

351
0
09-28-2023 03:05 PM
AaronWilliamsi3
New Contributor

This is a bug report. I'm not sure if this forum is the best place to report a bug in the ArcGIS Maps SDK for Unity. If there is a better place for this post, let me know and I'll move it there.

---

I've found an issue where terrain tiles on a tabletop-scale map (using ArcGISTabletopControllerComponent from the sample content) get placed in at the wrong locations if some very specific circumstances all converge at the same time.

In my testing, I've found that this issue only occurs if:

  1. ArcGISMapComponent.EngineToGeographic() or .GeographicToEngine() is called every frame during Update(),
  2. The map's center point is shifted on one frame by modifying ArcGISTabletopControllerComponent.Center, and
  3. The map's height is adjusted by modifying ArcGISTabletopControllerComponent.ElevationOffset on the next frame after the Center change.

If any of those three circumstances are missing, the bug does not occur. In my case, I was able to work around it by moving my EngineToGeographic() calls to LateUpdate().

If these three conditions do converge, however, some weird stuff starts happening. The existing terrain tiles stay fixed in their current positions while the map pans over them (creating an effect similar to moving a spotlight across the map), and any new terrain tiles that spawn in do so at the edge of the map and stay there.

terrain misplace.gif

To reproduce:

  1. Install the ArcGIS Maps SDK for Unity and import the sample assets from the Package Manager.
  2. Place the script below script (name the file "TerrainMisplaceRepro.cs") in your Assets folder:
  3. Open up the "Tabletop" sample scene. I'm using the URP oversion of the scene; I don't know if this also happens in HDRP.
  4. Attach a TerrainMisplaceRepro component to some object in the scene and drag the TabletopMap into its field.
  5. Hit play.

TerrainMisplaceRepro.cs:

 

 

using Esri.ArcGISMapsSDK.Samples.Components;
using Esri.GameEngine.Geometry;
using UnityEngine;

public class TerrainMisplaceRepro : MonoBehaviour
{
    public ArcGISTabletopControllerComponent tabletopController;
    
    // Update is called once per frame
    void Update()
    {
        ArcGISPoint center = tabletopController.Center;
        ArcGISPoint newCenter = new ArcGISPoint(center.X, center.Y + 100, center.Z, center.SpatialReference);
        tabletopController.Center = newCenter;
        tabletopController.ElevationOffset += 1;
        tabletopController.MapComponent.EngineToGeographic(Vector3.zero);
    }
}

 

You should see the "moving spotlight" effect as the map extent circle slides across the screen, followed by all the new terrain tiles piling up at the edge of the map.

I've no idea why this happens; all I know is that it does. Hopefully this is enough information for y'all to reproduce this on your end. If not, let me know and I can provide an actual repro project.

For context: I'm trying to build an app for the Magic Leap 2 that displays a map at tabletop scale, which the user can pan and scale. I encountered this bug while trying to write a script to keep the map's real-world height consistent as the user zooms in and pans over rough terrain. This doesn't seem to have anything to do with MagicLeap, though, as I was able to reproduce it in a project without the MagicLeap SDK. And in any case, I was able to fix the problem on my end by moving the code that was calling EngineToGeographic() every frame to LateUpdate.

Unity version 2022.2.0f1

ArcGIS Maps SDK for Unity version 1.3.0

---

Update: It appears that EngineToGeographic() and GeographicToEngine() both fulfill condition #1 for this bug to occur equally well. Replacing line 16 in my TerrainMisplaceRepro.cs script above with this line gave identical results:

 

tabletopController.MapComponent.GeographicToEngine(new ArcGISPoint(0, 0, 0, ArcGISSpatialReference.WGS84()));

 

---

Update 2: After further testing, I've found that the bug still occurs if I call EngineToGeographic() (or GeographicToEngine()) in a coroutine after a yield return null; or yield return new WaitForSeconds(); statement. However, the bug does not occur if the EngineToGeographic() call is after yield return new WaitForEndOfFrame(); in a coroutine, or if it's in LateUpdate() (as mentioned above), in FixedUpdate(), in an InputAction.performed event handler (from Unity's Input System package), or in an event handler for the ArcGISMapComponent.ExtentUpdated event.

However, I've also discovered that the bug does occur once again if all three of the necessary conditions identified above occur within LateUpdate() or within FixedUpdate(). That is, changing line 10 in the script shown above to either void FixedUpdate() or void LateUpdate() still reproduces the issue.

Tags (1)
0 Kudos
0 Replies