create landscape in editor plugin


photo

Recommended Posts

Hi All,

A few months ago I started working with Unigine. Before that I used Unity3d. I am very enthusiastic about Unigine. To get to know Unigine I am working on an editor plugin to create heightmaps and terrain bitmaps from real world data. I'm using the REST api from Bing maps for the elevations and terrain bitmaps. No problems so far. The following images give an impression of the plugin.

ui.thumb.jpg.0394e4767a2ce6583286e34ece76d24f.jpg

Heightmap, terrain bitmap and 3d landscape

heightmap.jpg.f3fcb7dd25a738244083204dc99061c1.jpg          terrainmap.jpg.ef8c26ca970b570fa1a3f6177f328229.jpg         landscape.jpg.ad5e79215b4328fb14ad85bf64fb881f.jpg 

Now I want to create a terrain and layermap based on this data. The code is based on "Working with Landscape Terrain via Code" in the documentation. I get the following errors: test.lmap not found/load and no landscape asset has been created.

error.jpg.97aa1d7198ff09ddb37727c90997079b.jpg

I have tried several modifications in the code but nothing worked.
Does anyone have an idea?

 

 

 

 

 

  • Like 1
Link to post

Hi Silent,

Unfortunately, the proposed solution does not work.

Link to post

Without seeing the actual code it's hard to tell the root cause of the issue. Could you please give us more details? If you also can provide a minimal test scene with this behavior (it can be even without plugin itself) - it would help a lot.

Thanks!

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

Link to post

Hi Silent,

Enclosed the code for creating a terrain. The code is used in a basic c ++ project (SDK: Unigine community 2.12) with only a lighting, main_player and ground node. If more information is needed, please let me know.

code_create_terrain.txt

Link to post

roelof

Please try to replace the following line:

lmap->setPath(String::format("%s.lmap", lmapName.get()));

with

lmap->setPath(FileSystem::addVirtualFile(String::format("%s.lmap", lmapName.get())));

Thanks!

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

Link to post

Hi Silent,

Since the change didn't work, I went to see where else a setpath occurs. Then it turned out that change of

lmapCreator-> setPath (String :: format ("% s.lmap", lmapName.get ()));

in

lmapCreator-> setPath (FileSystem :: addVirtualFile (String :: format ("% s.lmap", lmapName.get ())));

the solution is.
I still have to figure out why the heightmap and albedo map are not loaded.

Thank you for the assistance.

 

Link to post
Hi Silent,

Too bad, it seemed to work. That was because I forgot to delete the test.lmap from the previous test. Any other suggestions?
 
Link to post

Could you please give us more details about your .lmap pipeline? Are you overwriting the same files each time? It's not completely clear what is happening.

Thanks!

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

Link to post

 

Hi Silent,

When the test function is run for the first time you will get the reported error message. However, a test.lmap is created in the project's data directory. If we close the project (without save world) and start it again, we see test.lmap in the asset browser and the file can be found if we run the test function again.

Link to post

So, here is the our variant of your code:

Spoiler

// function creating the Landscape Terrain object using the generated .lmap file
void createTerrain(const Unigine::UGUID &guid)
{
	using namespace Unigine;
	// create new terrain
	ObjectLandscapeTerrainPtr terrain = ObjectLandscapeTerrain::create();
	terrain->setActiveTerrain(true);
	terrain->setCollision(true, 0);
	terrain->setName("TestTerrain");
	terrain->setSaveToWorldEnabledRecursive(true);
	terrain->setShowInEditorEnabledRecursive(true);

	// create layer map based on created .lmap file
	LandscapeLayerMapPtr lmap = LandscapeLayerMap::create();
	lmap->setParent(Landscape::getActiveTerrain());
	lmap->setPath(guid.getFileSystemString());
	lmap->setName("test");
	lmap->setSize({1024, 1024});
	lmap->setHeightScale(1.0);
	lmap->setSaveToWorldEnabledRecursive(true);
	lmap->setShowInEditorEnabledRecursive(true);
}

QString createEmptyLandscapeMap(const QString &path,
		const QString &desired_name)
{
	QString name = desired_name;
	if (name.isEmpty())
		name = qsl("landscape.lmap");

	name = fs::makeUniqueFilename(name,
			[&path](const QString &unique_name) -> bool {
				return !fs::fileExists(fs::appendPath(path, unique_name));
			});

	QString filepath = fs::appendPath(path, name);
	auto creator = LandscapeMapFileCreator::create();
	creator->setPath(filepath.toCChar());

	as::LandscapeMapImportParams params;
	ivec2 resolution(params.resolution_x, params.resolution_y);
	ivec2 grid;
	ivec2 tilesize = calcOptimalTilesize(grid, resolution);

	creator->setResolution(resolution);
	creator->setGrid(grid);

	auto processor = [tilesize](LandscapeMapFileCreatorPtr, LandscapeImagesPtr images, int, int ) {
		fillEmptyLanscapeMap(images, tilesize);
	};

	auto callback = MakeCallback(&processor, &decltype(processor)::operator());
	creator->addCreateCallback(callback);

	creator->run(false, false);

	return filepath;
}

void fillEmptyLanscapeMap(const LandscapeImagesPtr &images, const Math::ivec2 &tilesize)
{
	// Heightmap
	ImagePtr heightmap = images->getHeight();
	if (!heightmap->create2D(tilesize.x, tilesize.y, Image::FORMAT_R32F))
		return;

	size_t size = heightmap->getWidth() * heightmap->getHeight();
	float *p = reinterpret_cast<float *>(heightmap->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		p[i] = 0.0f;

	// Heightmap Opacity
	ImagePtr opacity = images->getOpacityHeight();
	if (!opacity->create2D(tilesize.x, tilesize.y, Image::FORMAT_R32F))
		return;

	size = opacity->getWidth() * opacity->getHeight();
	p = reinterpret_cast<float *>(opacity->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		p[i] = 1.0f;

	// Albedo With Opacity
	ImagePtr albedo = images->getAlbedo();
	if (!albedo->create2D(tilesize.x, tilesize.y, Image::FORMAT_RGBA8))
		return;

	size = albedo->getWidth() * albedo->getHeight() * albedo->getNumChannels();
	unsigned char *puc = reinterpret_cast<unsigned char *>(albedo->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		puc[i] = 255;
}

void test()
{
	QString path = terrain::createEmptyLandscapeMap("/home/danvern/source/engine/data");
	createTerrain(Unigine::FileSystem::getGUID(TOCHAR(path)));
}

 

No errors or whatsoever. Can you please provide us a minimal reproduction code for your behavior?

Thanks!

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

Link to post

Hi Silent,

Thanks for the code. I will upload a terrain creation project with a minimal editor plugin with the appropriate code.

Link to post

Hi Silent,

I haven't had time to test the code yet. If I have a result I will let you know.

Link to post

Hi Silent,

I have tested your variant and get the same error. I also uploaded a project with a minimal version of the editor plugin.

Link to post

Please, check the modified sources in attachment. There were couple of issues with specific filesystem work under the Windows (no errors or whatsoever were on Linux).

We will see how we can improve this behavior in the future releases, so no additional code is required to do such task.

Thanks for the test scene!

TerrainPlugin.zip

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

Link to post

Hi Silent,

Thanks for the solution!

 

  • Thanks 1
Link to post