I'm trying to find a way to enable the map to remain in the same place (in world space) but have the ability to pan and zoom around it.
Imagine if the map was on a tabletop and the user could drag and pan around the map, but the map itself remained "stuck" to the tabletop (i.e remained in the same place.)
"Sea of Thieves" has the exact functionality of what I'm trying to do with the ArcGIS SDK.
I've set up a "local map" and tried moving the ArcGIS camera and the extents together (so they remain in sync) and whilst this allows me to pan the map and always see a cutout version (i.e. a rectangular table-sized map) essentially what is happening is the map is showing a rectangular masked version of the map at different points in world space.
In the case of moving the ArcGIS camera and map extents at the same time, as previously mentioned for users standing around the map (each with their own camera) what they would see is the map move away from them. This is based on how ESRI use the map extents to mask off different parts of the "world map", as opposed to updating the tiles on a static quad.
From experimenting, I've found a couple of approaches, but all of them seem a bit convoluted and I'm hoping there is a much easier way for what seems like a pretty common use case.
Move the ArcGIS camera and map extents (as seen above) but use a render texture to render what the ArcGIS camera sees (in this case the map) to a static quad and have another static camera look at the quad. This works however, firstly it seems performance overkill to need to do this (have 2 cameras rendering) and also it won't work for terrain elevations (as the texture will obviously be flat.) So a none starter.
Move the ArcGIS camera and map extents (as seen above) but move the ArcGIS map root transform relative to where the user is panning so it always appears in the same world space. I haven't implemented this yet, but it definitely feels like a better choice than the first solution.
Hopefully, someone out there has already come across this problem and could steer me in the right direction, as it feels like a pretty common use case.
This is a bit tricky as the ArcGIS camera won't be rendering but instead, users will be viewing the map from their own perspective cameras.
We'll need to find a way to update the extents and scale of the map to effectively be able to zoom into or out of the map whilst it remains at a fixed world scale (i.e. appears like a fixed "table-top" map.)
Exciting post Alex!
Also happy to see you got a strong understanding of the SDK because your second option was exactly what I was going to recommend. I haven't seen anyone else try this themself, so I believe you are in uncharted territory here.
In addition to moving the HPRoot you will also need to move the Map extent's center position at the same rate you are changing the HPRoot. The easiest way to do this would be to update the origin position on the map component to be the same as the extent center.
In addition, you will need to remove the HPTransform and ArcGISLocation component and the ArcGISCamera CONTROLLER component (you need to leave the ArcGISCamera component on the camera) from your camera GO.
You can then setup keyboard interactions to move the origin position and extent center to move the map around. The camera will stay static but you could create other interactions to move your camera around the seen.
If I were you I would work with the Origin Position and Extent center in a PCS like 3857 that way you can update the units in meters. Or you can use Unity positions and call arcGISMapComponent.View.WorldToGeographic to work in translation in unity space if that is something you are more familiar with.
Thinking more on it. You could also leave the ArcGIsLocation and HPTransform on the camera GO you would just need to apply the same transform to that position that you were applying to the origin and extent center to give the feeling the camera wasn't moving
Thanks for the feedback. We've managed to implement the panning functionality using fixed "table-top" extents (see video below.) Ignore us furiously moving the map around this was mainly to test whether it would be responsive if we were continuously panning.
The next thing we're trying to work out is how zooming would work with this approach.
Our ArcGIS camera won't actually be rendering anything as users will be viewing the "table-top" map from their own cameras. This complicates how zooming will work.
The current approach we've taken with zooming is to scale both the root map transform and the extents so we get a zoomed in version of the "table-top" map.
Our current zooming POC is a bit janky (see video above) but if we adust the scale, position and extents correctly in theory we should get a fixed map that can be zoomed in and out.
I'm just wondering what you think of this approach and if there is there a better solution to this problem?
Good to see the panning working. Unfortunately, the root component scale isn't something we necessarily support (you can see some weird artifacts at times in your second video where tiles become disconnected).
Something you could try for the zoom would be to have a parent object of the camera that you can move further and closer from the origin. You could then calculate a movement scale factor to apply to the actual camera based on the distance from the origin which would be able to give it the sense it was locked in place still
Thanks for the suggestion Matt, I've been working on this with Alex, and your suggested approach was a lot more stable in our experimental scenario:
However, taking this beyond an experiment, it wouldn't just be the map shown on the screen, there would be other things displayed around the map too. Following this approach, our main worry is that this would get difficult to work with very quickly, as we'd need to be transforming everything outside the map any time we zoom so that it appears in the same location relative to the map, and also so that it does not appear to grow / shrink in size as we zoom in / out. Another thing that complicates things a little bit is we'd be deploying to XR devices so the camera movement would be based on head movement.
We also would like to be able to rotate the map, but noticed that the map extents appear to not rotate properly with the map transform:
A solution that came to mind would be to rotate everything else outside the map about the map centre instead to give the illusion that the map is being rotated, very similarly to zooming, but it's another transformation to keep track of for everything outside the map.
This has us thinking about whether there might be any way we could make the map table more isolated - something we can move and rotate freely and work with more intuitively in scene space. This would've been a big draw of the render texture approach outlined in the initial post, if only we had a way of displaying the 3rd dimension in a similar way. Do any potential approaches come to mind that might help us with this?
Thanks again for your help.
The approaches @Matt_Nelson mentioned were the most robust ways we could find to achieve this.
So for panning, we move the ArcGISMapComponent's origin, the extents origin, and the location of the ArcGISCamera. The extents updates are unfortunately and appear to snap into position on a different frame to where the update is applied (would be great if you have any alternative solutions to update the extents immediately @Matt_Nelson - the video in @wengyuan1110 's recent post here demonstrates the issue). To get around this issue we are looking into changing the tile surface shader to do our own clipping so that it updates immediately.
As for zooming, since scaling the root transform isn't supported and results in disconnected tiles as shown in videos above, we went with instead having a child transform of the ArcGISMap which everything relative to the map (including the main camera) sits under. Zooming in / out will update the map extents and scale this transform, effectively making the camera move further away from the map as you zoom out, or closer as you zoom in to make it look like the map is a static table and not moving / changing in size. It's not a perfect solution as it means we now need to do scaling for any script values that were in world space since we now need to apply an additional scaling factor to those based on the zoom level, making it a bit messy / complicated in areas, but that was the only way we could get it working.
Hope this helps. If you have any other ideas / have any breakthroughs with this it would be great to know how else this problem might be solved.
Hi @Thomas-F and everyone. I am about to start using the SDK in VR and Unity. Reading through this thread, I was thinking about a workaround for the zoom feature. Would it be possible to use a second camera which is only for the map, then copy this to a RenderTexture in Unity, and use this texture on a GameObject that is the map GameObject visible to the user?
The second camera would be independent of the XR camera rig, thus scaling other objects would hopefully not be necessary. This is just an idea, I have not tried it yet.