Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Potentially useful Info] Google 3D cities available as OGC 3D tiles #279

Open
jo-chemla opened this issue May 11, 2023 · 5 comments
Open

Comments

@jo-chemla
Copy link

jo-chemla commented May 11, 2023

Probably useful at some point, Google just released all its 2500 cities datasets as OGC/Cesium 3D-tiles at its GoogleIO-May2023 conference. The 3D-tiles standard is made to stream datasets - rather than download offline/merged 3D models - and is compatible through cesium libs with UnrealEngine, Unity, CesiumJS, Nvidia OmniVerse, deck-gl etc.

Note:

  • at the moment there is no blender plugin to stream 3D tiles, hopefully one is in the works (feature request on the blender community forum and cesium forum)
  • There might be an oss 3D-tiles downloader/cropper/merger lying around which would result in the same feature-set than MapsModelImporter - downloading all tiles within polygon/bbox extent (at a given zoom level, or all leaves from tileset) and merging them, based off of oslandia/py3dtiles or vcityteam/py3dtilers

CesiumJS Demo | google release post | cesium blog post

@jo-chemla
Copy link
Author

Proof-of-concept from @OmarShehata on twitter.

@OmarShehata
Copy link

This would be super useful for a lot of people! Some more details from my process if it helps:

  • I rigged CesiumJS to print out the urls of all loaded tiles, but this isn't a very good approach because it includes a lot more than just the leaf tiles that you'd be interested in downloading
  • The individual glTF tiles all have ECEF transforms
  • Once merged with gltf-transform, I needed to transform all the tiles back to the origin, while retaining their relative position
  • One tricky part here is figuring out how to automatically orient it back to Y or Z up (I did this by hand)
  • It was 30mb exported from Blender, and 7mb after running through gltf-transform optimize (which does Draco compression I believe among lots of other things)
  • One thing users might want to control is the screen space error. I think I had set mine to 8 so it looks good but isn't too many tiles.

@t0stiman
Copy link

t0stiman commented Oct 2, 2023

Thanks to you I was able to create my own method of grabbing gmaps 3d tiles.

Downloading the tiles

  1. Follow these steps to create a Unity project: https://cesium.com/learn/unity/unity-photorealistic-3d-tiles/#step-1-add-photorealistic-3d-tiles-to-your-scene
  2. Create 2 scripts:

meshDownloader.cs

using System.Net;
using UnityEngine;

//attach this script to the Cesium3DTileset object
public class meshDownloader : MonoBehaviour
{
    public string outputFolder = @"D:\temp\maps\";
    
    public void idk()
    {
        // var baseObj = GameObject.Find("Cesium3DTileset");
        var baseObj = gameObject;
        int counter = 0;

        //if outputFolder doesnt end with a backslash, add one, 
        if (outputFolder[outputFolder.Length-1] != '\\')
        {
            outputFolder += @"\";
        }
        
        for (int i = 0; i < baseObj.transform.childCount; i++)
        {
            var tile = baseObj.transform.GetChild(i).gameObject;
            if (tile.activeSelf && tile.name.Contains(".glb"))
            {                
                //download
                using (var client = new WebClient())
                {
                    Debug.Log(counter+".glb");
                    client.DownloadFile(tile.name, outputFolder+counter+".glb");
                    counter++;
                }
            }
        }
    }
}

meshDownloaderButton.cs

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(meshDownloader))]
public class meshDownloaderButton : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        var myScript = (meshDownloader)target;
        if (GUILayout.Button("download"))
        {
            myScript.idk();
        }
    }
}
  1. Add the MeshDownloader script to the Cesium3DTileset object.
  2. On the Cesium 3D tileset component:
    • set maxium screen space error to 0 to get the highest quality tiles. This will take a heavy performance toll! It's better to use the default value if you want to make sure things work first.
    • set Show Tiles in Hierarchy (important)
  3. Enter an output folder in the Mesh Downloader component and click "download"

Merging the tiles

You can merge the GLB files to 1 file with glTF Transform https://gltf-transform.dev/

gltf-transform merge *

Moving the tiles to the center of the scene

  1. import the .glb files or the combined .glb into Blender (file -> import -> gltf 2.0)
  2. select all objects (a)
  3. shift-ctrl-alt-c -> origin to geometry
  4. shift-s -> selection to cursor (keep offset)

Rotating the objects so they're face-up

Example coordinates: 53.496306, 9.9503333

  1. Rotate on the Z axis: -longitude (-9.9503333)
  2. Rotate on the Y axis: -90+lattitude (-90+53.496306)

@t0stiman
Copy link

t0stiman commented Oct 2, 2023

One problem I'm still trying to solve is these gaps:

afbeelding

My theory is that these gaps are there because the meshes in the glb files are so far from the center of the scene. Blender uses floating point values to store positions, so the further from the center of the scene the meshes are, the less precise their position is stored.
I haven't been able to find a solution for this problem yet so if anyone who reads this has an idea, I'd love to know

@jo-chemla
Copy link
Author

jo-chemla commented Aug 29, 2024

Just crawling through my list of open threads, sorry for the ping.

@OmarShehata there are various ways to find that matrix-transform:

  • One has been implemented in js by Garrett Johnson, look at setLatLonToYUp here NASA-AMMOS/3DTilesRendererJS
  • Another one is a way we at iconem found to work quite well by, computeCrsTransform here, transforming coordinates of origin+3 axes from one CRS (EPSG:4978 for google 3D-tiles) to the other: to get the right vertical, and then shift so one tile is at the origin.
  • Public implementation is here to combine multiple georeferenced datasets expressed in different CRS (example with potree + Google 3D Cities, also work on app.iconem.com with splats, COPC, any 3Dtiles dataset etc)

@t0stiman Floating-point precision errors result when the whole matrix transform pipeline is not applied in one go - eg your tiles are far from the origin, and the camera is far as well to. In the local coordinate system of each tile, these precision errors are not present. You can try to apply the same matrix-transform that would move the whole tileset closer to the origin.

Note for blender users willing to download a sample of 3d-tiles data, the BLOSM python implementation is a great way to do it - @vvoovv just implemented custom 3d-tileset tileset.json endpoint support - and Cesium Ion introduced Offline Clips of 3D Tiles

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants