WGS84 objects in the Cesium Omniverse

Hi there,
love the Cesium for Omniverse plugin!
What I am struggling with is the projection: is there a way to position objects in WGS84 coordinates? Or is there a “how-to” to re-project/position objects into the cesium reference system?
Also, when I want to add huge objects (country boundaries for example), those appear “flat”, while the cesium terrain is curved…
Any idea?

Hi @asindl

To answer your first question, we plan to add support for globe anchoring soon. That will let you assign a lat/long to an arbitrary prim and have it stay anchored to the globe.

However for your use case you would need to use PROJ (or similar library) to transform projected coordinates into ECEF coordinates and then into local USD coordinates based on the georeference position (see computeEcefToUsdTransform). Then you would create your USD geometry.

Unfortunately I don’t have any sample code handy, but it sounds like an interesting problem and I’m curious to see what you come up with. It’s possible we’ll expose some helpers to do this in the future.

Thanks @sean_lilley,
I was able to transform my objects into ECEF. But I am struggling with the transformation “into local USD coordinates”. I guess, you mean relative to the coordinates, I can set in the Cesium prim in the Omniverse Create stage view, correct? I guess, based on the lat/lan, there is also some rotation involved.
Furthermore, the cesium data seems to be in centimeters with the z-axis pointing “down”?!
One thing I tried was to set the cesium world reference to 0,0,-6378137 to center it in the ECEF origin. Results were quite promising, but still had a bit of a lon offset in there.

Yes, you would need to use the georeference origin in the Cesium prim. computeEcefToUsdTransform is how we do it on the C++ side.

There’s three parts to that:

  • Transform ECEF to East North Up (ENU) based on the georeference origin
  • Transform z-up to the USD up-axis (usually y-up)
  • Transform meters to the USD units (usually cm)

For Cesium tiles the full sequence of transformations is:

glTF scene graphY_UP_TO_Z_UPtile transformECEF to ENUZ_UP_TO_Y_UPm to cm

We probably want to expose more of this math on the Python side.

1 Like

Just to follow up here, if you need to get the ECEF to USD transform we now store that in the /CesiumSession prim.

import omni.usd
stage = omni.usd.get_context().get_stage()
cesium_prim = stage.GetPrimAtPath("/CesiumSession")
ecef_to_usd_transform = cesium_prim.GetAttribute("cesium:ecefToUsdTransform").Get()
print(ecef_to_usd_transform)

See https://github.com/CesiumGS/cesium-omniverse/pull/295 for details. This change went out in Cesium for Omniverse v0.7.0.

1 Like