Datasmith: Position inaccuracy in Terrain tiles exporting from City Engine

924
4
11-21-2021 05:12 PM
GabrielaRW
New Contributor II

Hi team, we are exporting ArcGis CityEngine terrain to Datasmith using CityEngine 2021.1. We are running into an issue with the position of the tiles in the datasmith file where they don’t quite match in the edges as per this screenshot:

 

GabrielaRW_0-1637541995261.png

 

We think this is related to the way that the scale is being set when exporting from CityEngine, which I am guessing is calculated using the maximum and minimum height of each GeoTiff tile individually, instead of the whole set.

GabrielaRW_1-1637541995265.png

 

The reason I believe this is the problem is that if you look at the Datasmith file (and corresponding imported landscapes), the scale X and Y is the same for all the landscapes but the Z varies ever so slightly (see the attached datasmith file).

 

Unfortunately we haven't found a way to modify how this is calculated when doing the export from CityEngine. 

We want to be able to set a uniform scale in the resulting datasmith file using a max and min height for the whole terrain. This would be, for example, from -50 (below sea level) to 480m (highest peak in the region). Do you know if there is any way to do this in CityEngine, manipulating the scene or at the time of export?

Have you seen this issue before? It seems to me like a potential bug because it would mean an inaccurate representation of the terrain in a scene when exporting to datasmith.

Your assistance is appreciated

0 Kudos
4 Replies
BenjaminNeukom
Esri Contributor

Hi @GabrielaRW!

 

Thanks for reaching out. I did some investigating.

 


which I am guessing is calculated using the maximum and minimum height of each GeoTiff tile individually


This is correct. We then basically follow these steps in the exporter to calculate the correct Z scaling.

 

instead of the whole set.


We don't calculate the Z scaling on the whole set because we are not modifying the elevation values of the heightmap we export (only the dimensions are changed to fit Unreals preferred landscape dimensions). This means for different heightmaps, the same grayscale value could mean different elevations.

We don't want them "to match" for the whole export set because that could mean we loose precision. Imagine a landscape with only a small elevation difference. For this landscape we have a lot of different grayscale values to represent this small elevation difference. Now if we added another landscape with a mountain and a large elevation difference we'd "loose" a lot values to represent the elevation of the first landscape.

But I don't think that's actually the problem. The problem is, that neighboring terrains could have slightly different elevations directly at the border. And because they are not connected you can see a small gap.

You can also see this issue already in CE:
CE_terrain_issue.JPG

For now I don't have a nice automatic solution to fix the issues. The only thing I can suggest, is modifying the terrain in Unreal afterwards to fix the issues or modifying the original heightmaps so they don't have these elevation differences at the border anymore.

 

Best,

Benjamin

 

0 Kudos
GabrielaRW
New Contributor II

Hi @BenjaminNeukom . See my response below:

We don't calculate the Z scaling on the whole set because we are not modifying the elevation values of the heightmap we export

You are converting GeoTiff files into PNG with a different bit depth and also changing the resolution, so you are indirectly modifying pixel values. See on the right the original file and on the left the converted file:

GabrielaRW_0-1639003345105.png

 

(only the dimensions are changed to fit Unreals preferred landscape dimensions).

You are actually not following the recommended Unreal Engine landscape sizes, the output of the Datasmith export is 2160 x 2160 with a component resolution of 128 x 128:

GabrielaRW_1-1639003345108.png

When Epic recommends the following values:

GabrielaRW_2-1639003345111.png

 

We don't want them "to match" for the whole export set because that could mean we loose precision. Imagine a landscape with only a small elevation difference. For this landscape we have a lot of different grayscale values to represent this small elevation difference. Now if we added another landscape with a mountain and a large elevation difference we'd "loose" a lot values to represent the elevation of the first landscape.

I would argue that the ‘precision’ that we are losing is minimal compared to the issue of having terrain that does not follow a uniform scale. What happens when we have another dataset, in our case 3d meshes with the buildings, that are situated in space on the Y axis using a uniform scale for the whole area (in this case the city of Wellington), and we put it on top of mismatched terrain tiles? They will sit nicely in some spot and in others they will intersect with the floor or float above it.

Even if you believe that the precision loss is an important factor, it should be up to the user to choose whether it is an acceptable trade off.

But I don't think that's actually the problem. The problem is, that neighboring terrains could have slightly different elevations directly at the border. And because they are not connected you can see a small gap.

We are already accounting for this issue. The heightmap tiles are exported in 2048 x 2048 with a pixel overlap with the neighbour tile. Then when we import them into CityEngine we modify the extents of the Layer to 2047 x 2047. We do not see the same imprecision or drops in our CityEngine scene, and we also don’t have the issue when exporting static meshes, they align correctly.

 

In the script that we are using to import the heightmaps, you can see the code that we use to account for oversampling.

def modify_dimensions_of_layer(layer):
    """
    Changes the dimensions of the terrain by removing 1 pixel to account for oversampling

    Args:
        layer: (obj) The terrain layer introduced in City Engine
    """
    current_extents = ce.getAttributeLayerExtents(layer)
    new_extents = [current_extents[0],
                   current_extents[1],
                   current_extents[2]-1,
                   current_extents[3]-1]
    ce.setAttributeLayerExtents(layer, new_extents)

We have contacted ESRI support (Esri Case #02940160) and Epic, and provided with required files and script to reproduce this issue, our understanding was that they were working on a fix. You are welcome to look at the files and scripts as well.

To recap:

  • Landscape recommended sizes for UE are not followed, this needs to be fixed.
  • The output scale needs to be something that you can choose, either to retain ‘precision’ and have different scales for each file or have uniformity and lose ‘precision’
  • We are already accounting for the border issue

 

0 Kudos
BenjaminNeukom
Esri Contributor

Hi @GabrielaRW 

 

Thanks for your response! I will do some more investigating so we can improve the situation hopefully!

 

In the meantime a workaround would be to export a triangulated mesh of the terrain using FBX (instead of a heightmap and Unreal landscapes using Datasmith). This could also help with issues where buildings do not sit perfectly on the terrain anymore (due to how Unreal landscapes are tessellated differently than CE landscapes).

Note that the Material in Unreal needs to be set to opaque after importing them.

 

Best,

Benjamin

 

0 Kudos
GabrielaRW
New Contributor II

Thanks for your reply @BenjaminNeukom . We are aware of the workaround with the static meshes and we have implemented it, including the material change when importing to Unreal Engine.

Keep us posted on changes to the Datasmith exporter when you can.

0 Kudos