Jump to content

Scaling Problem CityEngine / Unigine


photo

Recommended Posts

Hi all

 

I have a scaling problem between CityEngine and Unigine.

 

In the screenshot, the upper terrain is generated directly in Unigine using the new landscape tool comming with version 2.3.

The lower terrain is generated in CityEngine with exact the same GeoTiff as the other was generated and later exported to Unigine by FBX.

Somehow the two terrain do not have the same scale.

 

Is there a problem with the new landscape tool, or do I miss something?

Do I really have to scale the FBX import manually until it matches the landscape?

 

post-1904-0-83524500-1473147418_thumb.jpg

Link to comment

Hi Andrey

 

As Phil already mentioned we have a missmatch between the models from Unigines new landscape tool and the exported fbx/collada/obj objects from ESRI CityEngine. All our raw data is in WGS-84 and we are using the projection WGS84 Mercator in ESRI. Combining the export shows a large mismatch to Unigine's landscape. Since the landscape tool doesn't offer any options to configure the projection and representation in x-y-z coordinates, can you tell us the exact projection Unigine is expecting? So far it was impossible to overlay streets/house/etc from ESRI to the correct coordinate in WGS-84 in Unigine.

 

Best regards,

Renato

Link to comment

Hi Renato,

 

Landscape tool internally converting all the data to UTM projection (WGS 84 datum). Please, check if your terrain is not curved (or if you need curved terrain, please, check if you have added all nodes to the geodetic pivot, so they will become curved as well).

 

Since the Landscape tool is in experimental stage right now we recommend to use old approach with old Landscape tool to get correct import from 3rd party software.

 

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Renato,

 

I've checked attached files.

 

FBX file (if importing with scale = 1.0) will generate landscape with a size of 34x34km approx. In Geotiff texture there is 24x34km terrain heights that can be correctly imported via Landscape tool (24x34km landscape will be generated). Landscape tool is working as expected in this case.

 

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Andrey

 

We checked the projection in ESRI's CityEngine and can't find the exact projection to export there models as fbx so that they match with Unigine. We tried quite all different WGS-84 projections, and so far none of them fit with the landscape build within Unigine.

 

Any ideas, which projection we should use in ESRI?

 

kind regards,

Renato

Link to comment

Andrey,

 

I have a more or less fitting fbx model from ESRI by using the WGS-84 N32. Even if we use the same height model in Unigine and ESRI, it wont fit to an usable tolerance.

 

What is the proposed approach? To export the fbx or create an export script as you have done with the California/Washington sceneries?

 

Remark:

The position fits only in a very small range...

 

 

Thanks,

Renato

Link to comment
  • 1 year later...

Hi,

It seems, that there is no exact matching source projection to match projection that landscape / geodetic pivot use. So you need to write a conversation logic for your imported mesh.

There are 2 main steps:

First: you need to find out WGS84 latitude / longitude for your mesh points. The simplest way is to export geometry in geographic WGS84 projection, where x, y is already needed lon / lat. If not you can use UnigineDataset api that is a wrapper around gdal library:

Lets say you have a raster source file with needed geotransform data:

#include <UnigineDataset.h>
using namespace Unigine;

// see list of supported formats on http://www.gdal.org/formats_list.html
const char *filename = "some_raster_with_geodata.tif"

DatasetPtr dataset = Dataset::create();
if (!dataset->load(filename))
   Log::fatal("failed\n");


DatasetRasterPosResolverPtr resolver = dataset->getRasterPosResolver();
if (!resolver)
	Log::fatal("failed");

// coordinates of interest in raster space
int x = 500;
int y = 500;

// result
double lat, lon;
resolver->getGeodeticPosition(x, y, lat, lon);

Or you know source  projection string in wkt format and geotransforms coefficients (article about gdal dataset: http://www.gdal.org/gdal_datamodel.html) :

#include <UnigineDataset.h>
using namespace Unigine;

// define a wkt projection, quotes are backslashed (Generated from Global mapper: Gauss Kruger (6 degree zones) Zone 56(30W - 24W))
String projection(
"PROJCS[\"Transverse_Mercator\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS84\",SPHEROID[\"WGS84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],"
"UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"scale_factor\",1],PARAMETER[\"central_meridian\",-27],"
"PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"false_easting\",56500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]");

// size of our raster source
int size_x = 1000;
int size_y = 1000;

// raster transforms
const double transforms[6] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
Unigine::DatasetRasterPosResolverPtr resolver = DatasetRasterPosResolver::create(transforms, projection.get(), size_x, size_y);
if (!resolver)
	Log::fatal("failed");

// coordinates of interest in raster space (in given projection)
int x = 500;
int y = 500;

// result
double lat, lon;
resolver->getGeodeticPosition(x, y, lat, lon);

 

Second: when we have points in lat / lon, we use GeodeticPivot api to convert it into local coordinates. Take geodetic pivot node, that is created by landscape tool (or create a new one,  with pivot taken from landscape tool project's center point) and use GeodeticPivot::mapGeodeticToFlat to get local point.

 

So your algorithm can be like this:

// Open imported mesh
MeshPtr mesh = Mesh::create("mesh_path");

// or take from object
ObjectMeshStaticPtr object;
MeshPtr mesh;
object->getMesh(mesh);

// iterate over mesh vertices
for (int s = 0; s < mesh->getNumSurfaces(); s++)
{
	for (int i = 0; i < mesh->getNumVertex(s); i++)
    {
		Math::vec3 vertex = mesh->getVertex(i, s);
		// find lat / lon with previous code snippets
		double lat, lon;
		
		Math::dvec3 local_pos = geodetic_pivot->mapGeodeticToFlat(Math::dvec3(lon, lat, 0));
		
		// set vertex
		mesh->setVertex(i, Math::vec3(local_pos), s);
    }
}
  

 

Please test this and post the results.

Link to comment
×
×
  • Create New...